ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
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  // Set default prefs
1058  $this->userObj->setPref('hits_per_page', $this->settings->get('hits_per_page', '30'));
1059 
1060  if (count($this->prefs)) {
1061  foreach ($this->prefs as $key => $value) {
1062  if ($key !== 'mail_incoming_type' &&
1063  $key !== 'mail_signature' &&
1064  $key !== 'mail_linebreak'
1065  ) {
1066  $this->userObj->setPref($key, $value);
1067  }
1068  }
1069  }
1070 
1071  if (!is_array($this->prefs) || !array_key_exists('chat_osc_accept_msg', $this->prefs)) {
1072  $this->userObj->setPref('chat_osc_accept_msg', $this->settings->get('chat_osc_accept_msg', 'n'));
1073  }
1074  if (!is_array($this->prefs) || !array_key_exists('chat_broadcast_typing', $this->prefs)) {
1075  $this->userObj->setPref('chat_broadcast_typing', $this->settings->get('chat_broadcast_typing', 'n'));
1076  }
1077  if (!is_array($this->prefs) || !array_key_exists('bs_allow_to_contact_me', $this->prefs)) {
1078  $this->userObj->setPref('bs_allow_to_contact_me', $this->settings->get('bs_allow_to_contact_me', 'n'));
1079  }
1080 
1081  $this->userObj->writePrefs();
1082 
1083  // update mail preferences, to be extended
1084  $this->updateMailPreferences($this->userObj->getId());
1085 
1086  if (is_array($this->personalPicture)) {
1087  if (strlen($this->personalPicture['content'])) {
1088  $extension = 'jpg';
1089  if (preg_match('/.*(png|jpg|gif|jpeg)$/', $this->personalPicture['imagetype'], $matches)) {
1090  $extension = $matches[1];
1091  }
1092  $tmp_name = $this->saveTempImage($this->personalPicture['content'], ".{$extension}");
1093  if (strlen($tmp_name)) {
1094  ilObjUser::_uploadPersonalPicture($tmp_name, $this->userObj->getId());
1095  unlink($tmp_name);
1096  }
1097  }
1098  }
1099 
1100  //set role entries
1101  foreach ($this->roles as $role_id => $role) {
1102  if (isset($this->role_assign[$role_id]) && $this->role_assign[$role_id]) {
1103  $this->assignToRole($this->userObj, (int) $this->role_assign[$role_id]);
1104  }
1105  }
1106 
1107  if (count($this->udf_data)) {
1108  $udd = new ilUserDefinedData($this->userObj->getId());
1109  foreach ($this->udf_data as $field => $value) {
1110  $udd->set('f_' . $field, $value);
1111  }
1112  $udd->update();
1113  }
1114 
1115  $this->sendAccountMail();
1116  $this->logSuccess($this->userObj->getLogin(), $this->userObj->getId(), 'Insert');
1117  // reset account mail object
1118  $this->acc_mail->reset();
1119  }
1120  break;
1121 
1122  case 'Update':
1123  if (!$user_id) {
1124  $this->logFailure($this->userObj->getLogin(), $this->lng->txt('usrimport_cant_update'));
1125  } else {
1126  $updateUser = new ilObjUser($user_id);
1127  $updateUser->read();
1128  $updateUser->readPrefs();
1129  if ($this->currPassword != null) {
1130  switch (strtoupper($this->currPasswordType)) {
1131  case 'BCRYPT':
1132  $updateUser->setPasswd($this->currPassword, ilObjUser::PASSWD_CRYPTED);
1133  $updateUser->setPasswordEncodingType('bcryptphp');
1134  $updateUser->setPasswordSalt(null);
1135  break;
1136 
1137  case 'PLAIN':
1138  $updateUser->setPasswd($this->currPassword, ilObjUser::PASSWD_PLAIN);
1139  $this->acc_mail->setUserPassword((string) $this->currPassword);
1140  break;
1141 
1142  default:
1143  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_attribute_value_illegal'), 'Type', 'Password', $this->stripTags($this->currPasswordType)));
1144  break;
1145  }
1146  }
1147  if ($this->tagContained('Firstname')) {
1148  $updateUser->setFirstname($this->userObj->getFirstname());
1149  }
1150  if ($this->tagContained('Lastname')) {
1151  $updateUser->setLastname($this->userObj->getLastname());
1152  }
1153  if ($this->tagContained('Title')) {
1154  $updateUser->setUTitle($this->userObj->getUTitle());
1155  }
1156  if ($this->tagContained('Gender')) {
1157  $updateUser->setGender($this->userObj->getGender());
1158  }
1159  if ($this->tagContained('Email')) {
1160  $updateUser->setEmail($this->userObj->getEmail());
1161  }
1162  if ($this->tagContained('SecondEmail')) {
1163  $updateUser->setSecondEmail($this->userObj->getSecondEmail());
1164  }
1165  if ($this->tagContained('Birthday')) {
1166  $updateUser->setBirthday($this->userObj->getBirthday());
1167  }
1168  if ($this->tagContained('Institution')) {
1169  $updateUser->setInstitution($this->userObj->getInstitution());
1170  }
1171  if ($this->tagContained('Street')) {
1172  $updateUser->setStreet($this->userObj->getStreet());
1173  }
1174  if ($this->tagContained('City')) {
1175  $updateUser->setCity($this->userObj->getCity());
1176  }
1177  if ($this->tagContained('PostalCode')) {
1178  $updateUser->setZipcode($this->userObj->getZipcode());
1179  }
1180  if ($this->tagContained('Country')) {
1181  $updateUser->setCountry($this->userObj->getCountry());
1182  }
1183  if ($this->tagContained('SelCountry')) {
1184  $updateUser->setSelectedCountry($this->userObj->getSelectedCountry());
1185  }
1186  if ($this->tagContained('PhoneOffice')) {
1187  $updateUser->setPhoneOffice($this->userObj->getPhoneOffice());
1188  }
1189  if ($this->tagContained('PhoneHome')) {
1190  $updateUser->setPhoneHome($this->userObj->getPhoneHome());
1191  }
1192  if ($this->tagContained('PhoneMobile')) {
1193  $updateUser->setPhoneMobile($this->userObj->getPhoneMobile());
1194  }
1195  if ($this->tagContained('Fax')) {
1196  $updateUser->setFax($this->userObj->getFax());
1197  }
1198  if ($this->tagContained('Hobby')) {
1199  $updateUser->setHobby($this->userObj->getHobby());
1200  }
1201  if ($this->tagContained('GeneralInterest')) {
1202  $updateUser->setGeneralInterests($this->userObj->getGeneralInterests());
1203  }
1204  if ($this->tagContained('OfferingHelp')) {
1205  $updateUser->setOfferingHelp($this->userObj->getOfferingHelp());
1206  }
1207  if ($this->tagContained('LookingForHelp')) {
1208  $updateUser->setLookingForHelp($this->userObj->getLookingForHelp());
1209  }
1210  if ($this->tagContained('Comment')) {
1211  $updateUser->setComment($this->userObj->getComment());
1212  }
1213  if ($this->tagContained('Department')) {
1214  $updateUser->setDepartment($this->userObj->getDepartment());
1215  }
1216  if ($this->tagContained('Matriculation')) {
1217  $updateUser->setMatriculation($this->userObj->getMatriculation());
1218  }
1219  if (!is_null($this->currActive)) {
1220  $updateUser->setActive($this->currActive === 'true', is_object($this->user) ? $this->user->getId() : 0);
1221  }
1222  if ($this->tagContained('ClientIP')) {
1223  $updateUser->setClientIP($this->userObj->getClientIP());
1224  }
1225  if ($this->time_limit_set) {
1226  $updateUser->setTimeLimitUnlimited($this->userObj->getTimeLimitUnlimited());
1227  }
1228  if ($this->tagContained('TimeLimitFrom')) {
1229  $updateUser->setTimeLimitFrom($this->userObj->getTimeLimitFrom());
1230  }
1231  if ($this->tagContained('TimeLimitUntil')) {
1232  $updateUser->setTimeLimitUntil($this->userObj->getTimeLimitUntil());
1233  }
1234  if ($this->tagContained('TimeLimitMessage')) {
1235  $updateUser->setTimeLimitMessage($this->userObj->getTimeLimitMessage());
1236  }
1237  if ($this->tagContained('ApproveDate')) {
1238  $updateUser->setApproveDate($this->userObj->getApproveDate());
1239  }
1240  if ($this->tagContained('AgreeDate')) {
1241  $updateUser->setAgreeDate($this->userObj->getAgreeDate());
1242  }
1243  if ($this->tagContained('Language')) {
1244  $updateUser->setLanguage($this->userObj->getLanguage());
1245  }
1246  if ($this->tagContained('ExternalAccount')) {
1247  $updateUser->setExternalAccount($this->userObj->getExternalAccount());
1248  }
1249 
1250  // Fixed: if auth_mode is not set, it was always overwritten with auth_default
1251  #if (! is_null($this->userObj->getAuthMode())) $updateUser->setAuthMode($this->userObj->getAuthMode());
1252  if ($this->auth_mode_set) {
1253  $updateUser->setAuthMode($this->userObj->getAuthMode());
1254  }
1255 
1256  // Special handlin since it defaults to 7 (USER_FOLDER_ID)
1257  if ($this->time_limit_owner_set) {
1258  $updateUser->setTimeLimitOwner($this->userObj->getTimeLimitOwner());
1259  }
1260 
1261  if (count($this->prefs)) {
1262  foreach ($this->prefs as $key => $value) {
1263  if ($key !== 'mail_incoming_type' &&
1264  $key !== 'mail_signature' &&
1265  $key !== 'mail_linebreak'
1266  ) {
1267  $updateUser->setPref($key, $value);
1268  }
1269  }
1270  }
1271 
1272  // save user preferences (skin and style)
1273  if ($this->updateLookAndSkin) {
1274  $updateUser->setPref('skin', $this->userObj->getPref('skin'));
1275  $updateUser->setPref('style', $this->userObj->getPref('style'));
1276  }
1277 
1278 
1279  $updateUser->writePrefs();
1280 
1281  // update mail preferences, to be extended
1282  $this->updateMailPreferences($updateUser->getId());
1283 
1284  // #8759
1285  if (count($this->udf_data)) {
1286  $updateUser->setUserDefinedData($this->udf_data);
1287  }
1288 
1289  $updateUser->setProfileIncomplete($this->checkProfileIncomplete($updateUser));
1290  $updateUser->setFullname();
1291  $updateUser->setTitle($updateUser->getFullname());
1292  $updateUser->setDescription($updateUser->getEmail());
1293  $updateUser->update();
1294 
1295  if (count($this->udf_data)) {
1296  $udd = new ilUserDefinedData($updateUser->getId());
1297  foreach ($this->udf_data as $field => $value) {
1298  $udd->set('f_' . $field, $value);
1299  }
1300  $udd->update();
1301  }
1302 
1303  // update login
1304  if ($this->tagContained('Login') && $this->user_id != -1) {
1305  try {
1306  $updateUser->updateLogin($this->userObj->getLogin());
1307  } catch (ilUserException $e) {
1308  }
1309  }
1310 
1311 
1312  // if language has changed
1313 
1314  if (is_array($this->personalPicture)) {
1315  if (strlen($this->personalPicture['content'])) {
1316  $extension = 'jpg';
1317  if (preg_match('/.*(png|jpg|gif|jpeg)$/', $this->personalPicture['imagetype'], $matches)) {
1318  $extension = $matches[1];
1319  }
1320  $tmp_name = $this->saveTempImage($this->personalPicture['content'], ".{$extension}");
1321  if (strlen($tmp_name)) {
1322  ilObjUser::_uploadPersonalPicture($tmp_name, $updateUser->getId());
1323  unlink($tmp_name);
1324  }
1325  }
1326  }
1327 
1328 
1329  //update role entries
1330  //-------------------
1331  foreach ($this->roles as $role_id => $role) {
1332  if (array_key_exists($role_id, $this->role_assign)) {
1333  switch ($role['action']) {
1334  case 'Assign':
1335  $this->assignToRole($updateUser, (int) $this->role_assign[$role_id]);
1336  break;
1337  case 'AssignWithParents':
1338  $this->assignToRoleWithParents($updateUser, (int) $this->role_assign[$role_id]);
1339  break;
1340  case 'Detach':
1341  $this->detachFromRole($updateUser, (int) $this->role_assign[$role_id]);
1342  break;
1343  }
1344  }
1345  }
1346  $this->logSuccess($updateUser->getLogin(), $user_id, 'Update');
1347  }
1348  break;
1349  case 'Delete':
1350  if (!$user_id) {
1351  $this->logFailure($this->userObj->getLogin(), $this->lng->txt('usrimport_cant_delete'));
1352  } else {
1353  $deleteUser = new ilObjUser($user_id);
1354  $deleteUser->delete();
1355 
1356  $this->logSuccess($this->userObj->getLogin(), $user_id, 'Delete');
1357  }
1358  break;
1359  }
1360 
1361  // init role array for next user
1362  $this->roles = [];
1363  break;
1364 
1365  case 'Login':
1366  $this->userObj->setLogin($this->getCDataWithoutTags($this->cdata));
1367  break;
1368 
1369  case 'Password':
1370  $this->currPassword = $this->cdata;
1371  break;
1372 
1373  case 'Firstname':
1374  $this->userObj->setFirstname($this->getCDataWithoutTags($this->cdata));
1375  break;
1376 
1377  case 'Lastname':
1378  $this->userObj->setLastname($this->getCDataWithoutTags($this->cdata));
1379  break;
1380 
1381  case 'Title':
1382  $this->userObj->setUTitle($this->getCDataWithoutTags($this->cdata));
1383  break;
1384 
1385  case 'Gender':
1386  $this->userObj->setGender($this->cdata);
1387  break;
1388 
1389  case 'Email':
1390  $this->userObj->setEmail($this->getCDataWithoutTags($this->cdata));
1391  break;
1392  case 'SecondEmail':
1393  $this->userObj->setSecondEmail($this->getCDataWithoutTags($this->cdata));
1394  break;
1395  case 'Birthday':
1396  $birthday = $this->getCDataWithoutTags($this->cdata);
1397  if (strtotime($birthday) !== false) {
1398  $this->userObj->setBirthday($birthday);
1399  }
1400  break;
1401  case 'Institution':
1402  $this->userObj->setInstitution($this->getCDataWithoutTags($this->cdata));
1403  break;
1404 
1405  case 'Street':
1406  $this->userObj->setStreet($this->getCDataWithoutTags($this->cdata));
1407  break;
1408 
1409  case 'City':
1410  $this->userObj->setCity($this->getCDataWithoutTags($this->cdata));
1411  break;
1412 
1413  case 'PostalCode':
1414  $this->userObj->setZipcode($this->getCDataWithoutTags($this->cdata));
1415  break;
1416 
1417  case 'Country':
1418  $this->userObj->setCountry($this->getCDataWithoutTags($this->cdata));
1419  break;
1420 
1421  case 'SelCountry':
1422  $this->userObj->setSelectedCountry($this->getCDataWithoutTags($this->cdata));
1423  break;
1424 
1425  case 'PhoneOffice':
1426  $this->userObj->setPhoneOffice($this->getCDataWithoutTags($this->cdata));
1427  break;
1428 
1429  case 'PhoneHome':
1430  $this->userObj->setPhoneHome($this->getCDataWithoutTags($this->cdata));
1431  break;
1432 
1433  case 'PhoneMobile':
1434  $this->userObj->setPhoneMobile($this->getCDataWithoutTags($this->cdata));
1435  break;
1436 
1437  case 'Fax':
1438  $this->userObj->setFax($this->getCDataWithoutTags($this->cdata));
1439  break;
1440 
1441  case 'Hobby':
1442  $this->userObj->setHobby($this->getCDataWithoutTags($this->cdata));
1443  break;
1444 
1445  case 'GeneralInterest':
1446  case 'OfferingHelp':
1447  case 'LookingForHelp':
1448  $this->multi_values[$a_name][] = $this->getCDataWithoutTags($this->cdata);
1449  break;
1450 
1451  case 'Comment':
1452  $this->userObj->setComment($this->getCDataWithoutTags($this->cdata));
1453  break;
1454 
1455  case 'Department':
1456  $this->userObj->setDepartment($this->getCDataWithoutTags($this->cdata));
1457  break;
1458 
1459  case 'Matriculation':
1460  $this->userObj->setMatriculation($this->getCDataWithoutTags($this->cdata));
1461  break;
1462 
1463  case 'Active':
1464  $this->currActive = $this->cdata;
1465  break;
1466 
1467  case 'ClientIP':
1468  $this->userObj->setClientIP($this->getCDataWithoutTags($this->cdata));
1469  break;
1470 
1471  case 'TimeLimitOwner':
1472  $this->time_limit_owner_set = true;
1473  $this->userObj->setTimeLimitOwner((int) $this->cdata);
1474  break;
1475 
1476  case 'TimeLimitUnlimited':
1477  $this->time_limit_set = true;
1478  $this->userObj->setTimeLimitUnlimited((bool) $this->cdata);
1479  break;
1480 
1481  case 'TimeLimitFrom':
1482  if (is_numeric($this->cdata)) {
1483  // Treat cdata as a unix timestamp
1484  $this->userObj->setTimeLimitFrom((int) $this->cdata);
1485  } else {
1486  // Try to convert cdata into unix timestamp, or ignore it
1487  $timestamp = strtotime($this->cdata);
1488  if ($timestamp !== false && trim($this->cdata) !== '0000-00-00 00:00:00') {
1489  $this->userObj->setTimeLimitFrom($timestamp);
1490  } elseif ($this->cdata === '0000-00-00 00:00:00') {
1491  $this->userObj->setTimeLimitFrom(null);
1492  }
1493  }
1494  break;
1495 
1496  case 'TimeLimitUntil':
1497  if (is_numeric($this->cdata)) {
1498  // Treat cdata as a unix timestamp
1499  $this->userObj->setTimeLimitUntil((int) $this->cdata);
1500  } else {
1501  // Try to convert cdata into unix timestamp, or ignore it
1502  $timestamp = strtotime($this->cdata);
1503  if ($timestamp !== false && trim($this->cdata) !== '0000-00-00 00:00:00') {
1504  $this->userObj->setTimeLimitUntil($timestamp);
1505  } elseif ($this->cdata === '0000-00-00 00:00:00') {
1506  $this->userObj->setTimeLimitUntil(null);
1507  }
1508  }
1509  break;
1510 
1511  case 'TimeLimitMessage':
1512  $this->userObj->setTimeLimitMessage($this->cdata);
1513  break;
1514 
1515  case 'ApproveDate':
1516  $this->approve_date_set = true;
1517  if (is_numeric($this->cdata)) {
1518  // Treat cdata as a unix timestamp
1519  $tmp_date = new ilDateTime($this->cdata, IL_CAL_UNIX);
1520  $this->userObj->setApproveDate($tmp_date->get(IL_CAL_DATETIME));
1521  } else {
1522  // Try to convert cdata into unix timestamp, or ignore it
1523  $timestamp = strtotime($this->cdata);
1524  if ($timestamp !== false && trim($this->cdata) !== '0000-00-00 00:00:00') {
1525  $tmp_date = new ilDateTime($timestamp, IL_CAL_UNIX);
1526  $this->userObj->setApproveDate($tmp_date->get(IL_CAL_DATETIME));
1527  } elseif ($this->cdata === '0000-00-00 00:00:00') {
1528  $this->userObj->setApproveDate(null);
1529  }
1530  }
1531  break;
1532 
1533  case 'AgreeDate':
1534  if (is_numeric($this->cdata)) {
1535  // Treat cdata as a unix timestamp
1536  $tmp_date = new ilDateTime($this->cdata, IL_CAL_UNIX);
1537  $this->userObj->setAgreeDate($tmp_date->get(IL_CAL_DATETIME));
1538  } else {
1539  // Try to convert cdata into unix timestamp, or ignore it
1540  $timestamp = strtotime($this->cdata);
1541  if ($timestamp !== false && trim($this->cdata) !== '0000-00-00 00:00:00') {
1542  $tmp_date = new ilDateTime($timestamp, IL_CAL_UNIX);
1543  $this->userObj->setAgreeDate($tmp_date->get(IL_CAL_DATETIME));
1544  } elseif ($this->cdata === '0000-00-00 00:00:00') {
1545  $this->userObj->setAgreeDate(null);
1546  }
1547  }
1548  break;
1549 
1550  case 'ExternalAccount':
1551  $this->userObj->setExternalAccount($this->getCDataWithoutTags($this->cdata));
1552  break;
1553 
1554  case 'Look':
1555  $this->updateLookAndSkin = false;
1556  if ($this->skin !== '' && $this->style !== '') {
1557  if (is_array($this->userStyles)) {
1558  if (in_array($this->skin . ':' . $this->style, $this->userStyles)) {
1559  $this->userObj->setPref('skin', $this->skin);
1560  $this->userObj->setPref('style', $this->style);
1561  $this->updateLookAndSkin = true;
1562  }
1563  }
1564  }
1565  break;
1566 
1567  case 'UserDefinedField':
1569 
1570  $field_id = $udf->fetchFieldIdFromImportId($this->tmp_udf_id);
1571 
1572  if ($field_id === 0) {
1573  $field_id = $udf->fetchFieldIdFromName($this->tmp_udf_name);
1574  }
1575 
1576  if ($field_id === 0) {
1577  break;
1578  }
1579 
1580  $this->udf_data[$field_id] = strip_tags($this->cdata, ilObjAdvancedEditing::_getUsedHTMLTags('textarea'));
1581 
1582  break;
1583  case 'AccountInfo':
1584  if ($this->current_messenger_type === 'external') {
1585  $this->userObj->setExternalAccount($this->cdata);
1586  }
1587  break;
1588  case 'Pref':
1589  if ($this->currentPrefKey != null && strlen(trim($this->cdata)) > 0
1590  && ilUserXMLWriter::isPrefExportable($this->currentPrefKey)) {
1591  $this->prefs[$this->currentPrefKey] = trim($this->cdata);
1592  }
1593  $this->currentPrefKey = null;
1594  break;
1595  }
1596  }
1597 
1602  public function saveTempImage(
1603  string $image_data,
1604  string $filename
1605  ): string {
1606  $tempname = ilFileUtils::ilTempnam() . $filename;
1607  $fh = fopen($tempname, 'wb');
1608  if ($fh == false) {
1609  return '';
1610  }
1611  fwrite($fh, $image_data);
1612  fclose($fh);
1613  return $tempname;
1614  }
1615 
1619  public function verifyEndTag(
1620  $a_xml_parser,
1621  string $a_name
1622  ): void {
1623  $externalAccountHasChanged = false;
1624 
1625  switch ($a_name) {
1626  case 'Role':
1627  $this->roles[$this->current_role_id]['name'] = $this->cdata;
1628  $this->roles[$this->current_role_id]['type'] = $this->current_role_type;
1629  $this->roles[$this->current_role_id]['action'] = $this->current_role_action;
1630  break;
1631 
1632  case 'User':
1633  $this->userObj->setFullname();
1634  if ($this->user_id != -1 && ($this->action === 'Update' || $this->action === 'Delete')) {
1635  $user_id = $this->user_id;
1636  $user_exists = !is_null(ilObjUser::_lookupLogin($user_id));
1637  } else {
1638  $user_id = ilObjUser::getUserIdByLogin($this->userObj->getLogin());
1639  $user_exists = $user_id != 0;
1640  }
1641  if (is_null($this->userObj->getLogin())) {
1642  $this->logFailure('---', sprintf($this->lng->txt('usrimport_xml_element_for_action_required'), 'Login', 'Insert'));
1643  }
1644 
1645  if ($user_id === (int) ANONYMOUS_USER_ID || $user_id === (int) SYSTEM_USER_ID) {
1646  $this->logWarning($this->userObj->getLogin(), $this->lng->txt('usrimport_xml_anonymous_or_root_not_allowed'));
1647  break;
1648  }
1649 
1650  switch ($this->action) {
1651  case 'Insert':
1652  if ($user_exists and $this->conflict_rule === self::IL_FAIL_ON_CONFLICT) {
1653  $this->logWarning($this->userObj->getLogin(), $this->lng->txt('usrimport_cant_insert'));
1654  }
1655  if (is_null($this->userObj->getGender()) && $this->isFieldRequired('gender')) {
1656  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_for_action_required'), 'Gender', 'Insert'));
1657  }
1658  if (is_null($this->userObj->getFirstname())) {
1659  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_for_action_required'), 'Firstname', 'Insert'));
1660  }
1661  if (is_null($this->userObj->getLastname())) {
1662  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_for_action_required'), 'Lastname', 'Insert'));
1663  }
1664  if (count($this->roles) == 0) {
1665  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_for_action_required'), 'Role', 'Insert'));
1666  } else {
1667  $has_global_role = false;
1668  foreach ($this->roles as $role) {
1669  if ($role['type'] === 'Global') {
1670  $has_global_role = true;
1671  break;
1672  }
1673  }
1674  if (!$has_global_role) {
1675  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_global_role_for_action_required'), 'Insert'));
1676  }
1677  }
1678  break;
1679  case 'Update':
1680  if (!$user_exists) {
1681  $this->logWarning($this->userObj->getLogin(), $this->lng->txt('usrimport_cant_update'));
1682  } elseif ($this->user_id != -1 && $this->tagContained('Login')) {
1683  // check if someone owns the new login name!
1684  $someonesId = ilObjUser::_lookupId($this->userObj->getLogin());
1685 
1686  if (is_numeric($someonesId) && $someonesId != $this->user_id) {
1687  $this->logFailure($this->userObj->getLogin(), $this->lng->txt('usrimport_login_is_not_unique'));
1688  }
1689  }
1690  break;
1691  case 'Delete':
1692  if (!$user_exists) {
1693  $this->logWarning($this->userObj->getLogin(), $this->lng->txt('usrimport_cant_delete'));
1694  }
1695  break;
1696  }
1697 
1698  // init role array for next user
1699  $this->roles = [];
1700  break;
1701 
1702  case 'Login':
1703  if (array_key_exists($this->cdata, $this->logins)) {
1704  $this->logWarning($this->cdata, $this->lng->txt('usrimport_login_is_not_unique'));
1705  } else {
1706  $this->logins[$this->cdata] = $this->cdata;
1707  }
1708  $this->userObj->setLogin($this->stripTags($this->cdata));
1709  break;
1710 
1711  case 'Password':
1712  switch ($this->currPasswordType) {
1713  case 'BCRYPT':
1714  $this->userObj->setPasswd($this->cdata, ilObjUser::PASSWD_CRYPTED);
1715  $this->userObj->setPasswordEncodingType('bcryptphp');
1716  $this->userObj->setPasswordSalt(null);
1717  break;
1718 
1719  case 'PLAIN':
1720  $this->userObj->setPasswd($this->cdata, ilObjUser::PASSWD_PLAIN);
1721  $this->acc_mail->setUserPassword((string) $this->currPassword);
1722  break;
1723 
1724  default:
1725  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_attribute_value_illegal'), 'Type', 'Password', $this->stripTags($this->currPasswordType)));
1726  break;
1727  }
1728  break;
1729 
1730  case 'Firstname':
1731  $this->userObj->setFirstname($this->cdata);
1732  break;
1733 
1734  case 'Lastname':
1735  $this->userObj->setLastname($this->cdata);
1736  break;
1737 
1738  case 'Title':
1739  $this->userObj->setUTitle($this->cdata);
1740  break;
1741 
1742  case 'Gender':
1743  if (!in_array(strtolower($this->cdata), ['n', 'm', 'f', ''])) {
1744  $this->logFailure(
1745  $this->userObj->getLogin(),
1746  sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'Gender', $this->stripTags($this->cdata))
1747  );
1748  }
1749  $this->userObj->setGender($this->cdata);
1750  break;
1751 
1752  case 'Email':
1753  $this->userObj->setEmail($this->cdata);
1754  break;
1755  case 'SecondEmail':
1756  $this->userObj->setSecondEmail($this->cdata);
1757  break;
1758  case 'Institution':
1759  $this->userObj->setInstitution($this->cdata);
1760  break;
1761 
1762  case 'Street':
1763  $this->userObj->setStreet($this->cdata);
1764  break;
1765 
1766  case 'City':
1767  $this->userObj->setCity($this->cdata);
1768  break;
1769 
1770  case 'PostalCode':
1771  $this->userObj->setZipcode($this->cdata);
1772  break;
1773 
1774  case 'Country':
1775  $this->userObj->setCountry($this->cdata);
1776  break;
1777 
1778  case 'SelCountry':
1779  if (mb_strlen($this->cdata) !== 2) {
1780  $this->logFailure(
1781  $this->userObj->getLogin(),
1782  sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'SelCountry', $this->stripTags($this->cdata))
1783  );
1784  }
1785  $this->userObj->setSelectedCountry($this->cdata);
1786  break;
1787 
1788  case 'PhoneOffice':
1789  $this->userObj->setPhoneOffice($this->cdata);
1790  break;
1791 
1792  case 'PhoneHome':
1793  $this->userObj->setPhoneHome($this->cdata);
1794  break;
1795 
1796  case 'PhoneMobile':
1797  $this->userObj->setPhoneMobile($this->cdata);
1798  break;
1799 
1800  case 'Fax':
1801  $this->userObj->setFax($this->cdata);
1802  break;
1803 
1804  case 'Hobby':
1805  $this->userObj->setHobby($this->cdata);
1806  break;
1807 
1808  case 'GeneralInterest':
1809  case 'OfferingHelp':
1810  case 'LookingForHelp':
1811  $this->multi_values[$a_name][] = $this->cdata;
1812  break;
1813 
1814  case 'Comment':
1815  $this->userObj->setComment($this->cdata);
1816  break;
1817 
1818  case 'Department':
1819  $this->userObj->setDepartment($this->cdata);
1820  break;
1821 
1822  case 'Matriculation':
1823  $this->userObj->setMatriculation($this->cdata);
1824  break;
1825 
1826  case 'ExternalAccount':
1827  $am = ($this->userObj->getAuthMode() === 'default' || $this->userObj->getAuthMode() == '')
1828  ? ilAuthUtils::_getAuthModeName($this->settings->get('auth_mode'))
1829  : $this->userObj->getAuthMode();
1830  $loginForExternalAccount = (trim($this->cdata) == '')
1831  ? ''
1832  : ilObjUser::_checkExternalAuthAccount($am, trim($this->cdata));
1833  switch ($this->action) {
1834  case 'Insert':
1835  if ($loginForExternalAccount != '') {
1836  $this->logWarning($this->userObj->getLogin(), $this->lng->txt('usrimport_no_insert_ext_account_exists') . ' (' . $this->stripTags($this->cdata) . ')');
1837  }
1838  break;
1839 
1840  case 'Update':
1841  if ($loginForExternalAccount != '') {
1842  $externalAccountHasChanged = trim($this->cdata) != ilObjUser::_lookupExternalAccount($this->user_id);
1843  if ($externalAccountHasChanged && trim($loginForExternalAccount) != trim($this->userObj->getLogin())) {
1844  $this->logWarning(
1845  $this->userObj->getLogin(),
1846  $this->lng->txt('usrimport_no_update_ext_account_exists') . ' (' . $this->stripTags($this->cdata) . ' for ' . $this->stripTags($loginForExternalAccount) . ')'
1847  );
1848  }
1849  }
1850  break;
1851  }
1852  if ($externalAccountHasChanged) {
1853  $this->userObj->setExternalAccount(trim($this->cdata));
1854  }
1855  break;
1856 
1857  case 'Active':
1858  if ($this->cdata !== 'true'
1859  && $this->cdata !== 'false') {
1860  $this->logFailure(
1861  $this->userObj->getLogin(),
1862  sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'Active', $this->stripTags($this->cdata))
1863  );
1864  }
1865  $this->currActive = $this->cdata;
1866  break;
1867  case 'TimeLimitOwner':
1868  if (!preg_match('/\d+/', $this->cdata)) {
1869  $this->logFailure(
1870  $this->userObj->getLogin(),
1871  sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'TimeLimitOwner', $this->stripTags($this->cdata))
1872  );
1873  } elseif (!$this->access->checkAccess('cat_administrate_users', '', (int) $this->cdata)) {
1874  $this->logFailure(
1875  $this->userObj->getLogin(),
1876  sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'TimeLimitOwner', $this->stripTags($this->cdata))
1877  );
1878  } elseif ($this->object_data_cache->lookupType($this->object_data_cache->lookupObjId((int) $this->cdata)) !== 'cat' && !(int) $this->cdata == USER_FOLDER_ID) {
1879  $this->logFailure(
1880  $this->userObj->getLogin(),
1881  sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'TimeLimitOwner', $this->stripTags($this->cdata))
1882  );
1883  }
1884  $this->userObj->setTimeLimitOwner((int) $this->cdata);
1885  break;
1886  case 'TimeLimitUnlimited':
1887  switch (strtolower($this->cdata)) {
1888  case 'true':
1889  case '1':
1890  $this->userObj->setTimeLimitUnlimited(true);
1891  break;
1892  case 'false':
1893  case '0':
1894  $this->userObj->setTimeLimitUnlimited(false);
1895  break;
1896  default:
1897  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'TimeLimitUnlimited', $this->stripTags($this->cdata)));
1898  break;
1899  }
1900  break;
1901  case 'TimeLimitFrom':
1902  // Accept datetime or Unix timestamp
1903  if (strtotime($this->cdata) === false && !is_numeric($this->cdata)) {
1904  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'TimeLimitFrom', $this->stripTags($this->cdata)));
1905  }
1906  $this->userObj->setTimeLimitFrom((int) $this->cdata);
1907  break;
1908  case 'TimeLimitUntil':
1909  // Accept datetime or Unix timestamp
1910  if (strtotime($this->cdata) === false && !is_numeric($this->cdata)) {
1911  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'TimeLimitUntil', $this->stripTags($this->cdata)));
1912  }
1913  $this->userObj->setTimeLimitUntil((int) $this->cdata);
1914  break;
1915  case 'TimeLimitMessage':
1916  switch (strtolower($this->cdata)) {
1917  case '1':
1918  $this->userObj->setTimeLimitMessage('1');
1919  break;
1920  case '0':
1921  $this->userObj->setTimeLimitMessage('0');
1922  break;
1923  default:
1924  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'TimeLimitMessage', $this->stripTags($this->cdata)));
1925  break;
1926  }
1927  break;
1928  case 'ApproveDate':
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'), 'ApproveDate', $this->stripTags($this->cdata)));
1932  }
1933  break;
1934  case 'AgreeDate':
1935  // Accept datetime or Unix timestamp
1936  if (strtotime($this->cdata) === false && !is_numeric($this->cdata) && !$this->cdata === '0000-00-00 00:00:00') {
1937  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'AgreeDate', $this->stripTags($this->cdata)));
1938  }
1939  break;
1940  case 'Pref':
1941  if ($this->currentPrefKey != null) {
1942  $this->verifyPref($this->currentPrefKey, $this->cdata);
1943  }
1944  }
1945  }
1946 
1951  public function handlerCharacterData(
1952  $a_xml_parser,
1953  string $a_data
1954  ): void {
1955  if ($a_data !== "\n") {
1956  $a_data = preg_replace('/\t+/', ' ', $a_data);
1957  }
1958 
1959  if (strlen($a_data) > 0) {
1960  $this->cdata .= $a_data;
1961  }
1962  }
1963 
1967  public function getCollectedRoles(): array
1968  {
1969  return $this->roles;
1970  }
1971 
1972  public function getUserCount(): int
1973  {
1974  return $this->userCount;
1975  }
1976 
1980  public function logWarning(
1981  string $aLogin,
1982  string $aMessage
1983  ): void {
1984  if (!array_key_exists($aLogin, $this->protocol)) {
1985  $this->protocol[$aLogin] = [];
1986  }
1987  if ($aMessage) {
1988  $this->protocol[$aLogin][] = $aMessage;
1989  }
1990  if ($this->error_level === self::IL_IMPORT_SUCCESS) {
1991  $this->error_level = self::IL_IMPORT_WARNING;
1992  }
1993  }
1994 
1998  public function logFailure(
1999  string $aLogin,
2000  string $aMessage
2001  ): void {
2002  if (!array_key_exists($aLogin, $this->protocol)) {
2003  $this->protocol[$aLogin] = [];
2004  }
2005  if ($aMessage) {
2006  $this->protocol[$aLogin][] = $aMessage;
2007  }
2008  $this->error_level = self::IL_IMPORT_FAILURE;
2009  }
2010 
2014  public function logSuccess(
2015  string $aLogin,
2016  int $userid,
2017  string $action
2018  ): void {
2019  $this->user_mapping[$userid] = ['login' => $aLogin, 'action' => $action, 'message' => 'successful'];
2020  }
2021 
2022 
2030  public function getProtocol(): array
2031  {
2032  return $this->protocol;
2033  }
2034 
2038  public function getProtocolAsHTML(string $a_log_title): string
2039  {
2040  $block = new ilTemplate('tpl.usr_import_log_block.html', true, true, 'Services/User');
2041  $block->setVariable('TXT_LOG_TITLE', $a_log_title);
2042  $block->setVariable('TXT_MESSAGE_ID', $this->lng->txt('login'));
2043  $block->setVariable('TXT_MESSAGE_TEXT', $this->lng->txt('message'));
2044  foreach ($this->getProtocol() as $login => $messages) {
2045  $block->setCurrentBlock('log_row');
2046  $reason = '';
2047  foreach ($messages as $message) {
2048  if ($reason == '') {
2049  $reason = $message;
2050  } else {
2051  $reason .= '<br>' . $message;
2052  }
2053  }
2054  $block->setVariable('MESSAGE_ID', $login);
2055  $block->setVariable('MESSAGE_TEXT', $reason);
2056  $block->parseCurrentBlock();
2057  }
2058  return $block->get();
2059  }
2060 
2064  public function isSuccess(): bool
2065  {
2066  return $this->error_level === self::IL_IMPORT_SUCCESS;
2067  }
2068 
2073  public function getErrorLevel(): int
2074  {
2075  return $this->error_level;
2076  }
2077 
2082  public function getUserMapping(): array
2083  {
2084  return $this->user_mapping;
2085  }
2086 
2090  public function sendAccountMail(): void
2091  {
2092  if ($this->req_send_mail != '' ||
2093  ($this->isSendMail() && $this->userObj->getEmail() != '')) {
2094  $this->acc_mail->setUser($this->userObj);
2095  $this->acc_mail->send();
2096  }
2097  }
2098 
2099  public function setSendMail(bool $value): void
2100  {
2101  $this->send_mail = $value;
2102  }
2103 
2104  public function isSendMail(): bool
2105  {
2106  return $this->send_mail;
2107  }
2108 
2114  public function setUserMappingMode(int $value): void
2115  {
2116  if ($value === self::IL_USER_MAPPING_ID || $value === self::IL_USER_MAPPING_LOGIN) {
2117  $this->mapping_mode = $value;
2118  } else {
2119  die('wrong argument using methode setUserMappingMethod in ' . __FILE__);
2120  }
2121  }
2122 
2127  public function getUserMappingMode(): int
2128  {
2129  return $this->mapping_mode;
2130  }
2131 
2135  private function readRequiredFields(): array
2136  {
2137  if (is_array($this->required_fields)) {
2138  return $this->required_fields;
2139  }
2140  foreach ($this->settings->getAll() as $field => $value) {
2141  if (strpos($field, 'require_') === 0 && $value == 1) {
2142  $value = substr($field, 8);
2143  $this->required_fields[$value] = $value;
2144  }
2145  }
2146  return $this->required_fields ?: [];
2147  }
2148 
2153  private function checkProfileIncomplete(ilObjUser $user_obj): bool
2154  {
2155  return $this->user_profile->isProfileIncomplete($user_obj);
2156  }
2157 
2164  protected function isFieldRequired(string $fieldname): bool
2165  {
2166  $requiredFields = $this->readRequiredFields();
2167  $fieldname = strtolower(trim($fieldname));
2168  return array_key_exists($fieldname, $requiredFields);
2169  }
2170 
2171  private function verifyPref(string $key, string $value): void
2172  {
2173  switch ($key) {
2174  case 'mail_linebreak':
2175  case 'hits_per_page':
2176  if (!is_numeric($value) || $value < 0) {
2177  $this->logFailure('---', "Wrong value '{$this->stripTags($value)}': Positiv numeric value expected for preference {$this->stripTags($key)}.");
2178  }
2179  break;
2180  case 'language':
2181  case 'skin':
2182  case 'style':
2183  case 'ilPageEditor_HTMLMode':
2184  case 'ilPageEditor_JavaScript':
2185  case 'ilPageEditor_MediaMode':
2186  case 'tst_javascript':
2187  case 'tst_lastquestiontype':
2188  case 'tst_multiline_answers':
2189  case 'tst_use_previous_answers':
2190  case 'graphicalAnswerSetting':
2191  case 'priv_feed_pass':
2192  $this->logFailure('---', "Preference {$this->stripTags($key)} is not supported.");
2193  break;
2194  case 'public_city':
2195  case 'public_country':
2196  case 'public_department':
2197  case 'public_email':
2198  case 'public_second_email':
2199  case 'public_fax':
2200  case 'public_hobby':
2201  case 'public_institution':
2202  case 'public_matriculation':
2203  case 'public_phone':
2204  case 'public_phone_home':
2205  case 'public_phone_mobile':
2206  case 'public_phone_office':
2207  case 'public_street':
2208  case 'public_upload':
2209  case 'public_zip':
2210  case 'public_interests_general':
2211  case 'public_interests_help_offered':
2212  case 'public_interests_help_looking':
2213  case 'send_info_mails':
2214  case 'bs_allow_to_contact_me':
2215  case 'chat_osc_accept_msg':
2216  case 'chat_broadcast_typing':
2217  case 'hide_own_online_status':
2218  if (!in_array($value, ['y', 'n', ''])) {
2219  $this->logFailure('---', "Wrong value '{$this->stripTags($value)}': Value 'y' or 'n' expected for preference {$this->stripTags($key)}.");
2220  }
2221  break;
2222  case 'public_profile':
2223  if (!in_array($value, ['y', 'n', 'g'])) {
2224  $this->logFailure('---', "Wrong value '{$this->stripTags($value)}': Value 'y', 'g' or 'n' expected for preference {$this->stripTags($key)}.");
2225  }
2226  break;
2227  case 'show_users_online':
2228  if (!in_array($value, ['y', 'n', 'associated'])) {
2229  $this->logFailure('---', "Wrong value '{$this->stripTags($value)}': Value 'y' or 'n' or 'associated' expected for preference {$this->stripTags($key)}.");
2230  }
2231  break;
2232  case 'mail_incoming_type':
2233  if (!in_array((int) $value, ['0','1','2'])) {
2234  $this->logFailure('---', "Wrong value '{$this->stripTags($value)}': Value '0' (LOCAL),'1' (EMAIL) or '2' (BOTH) expected for preference {$this->stripTags($key)}.");
2235  }
2236  break;
2237  case 'weekstart':
2238  if (!in_array($value, ['0','1'])) {
2239  $this->logFailure('---', "Wrong value '{$this->stripTags($value)}': Value '0' (Sunday) or '1' (Monday) expected for preference {$this->stripTags($key)}.");
2240  }
2241  break;
2242 
2243  case 'mail_signature':
2244  break;
2245  case 'user_tz':
2246  try {
2247  ilTimeZone::_getInstance($value);
2248  return;
2249  } catch (ilTimeZoneException $tze) {
2250  $this->logFailure('---', "Wrong value '{$this->stripTags($value)}': Invalid timezone $value detected for preference {$this->stripTags($key)}.");
2251  }
2252  break;
2253  default:
2254  if (!ilUserXMLWriter::isPrefExportable($key)) {
2255  $this->logFailure('---', "Preference {$this->stripTags($key)} is not supported.");
2256  }
2257  break;
2258  }
2259  }
2260 
2261  private function updateMailPreferences(int $usr_id): void
2262  {
2263  if (array_key_exists('mail_incoming_type', $this->prefs) ||
2264  array_key_exists('mail_signature', $this->prefs) ||
2265  array_key_exists('mail_linebreak', $this->prefs)
2266  ) {
2267  $mailOptions = new ilMailOptions($usr_id);
2268 
2269  $mailOptions->setSignature(array_key_exists('mail_signature', $this->prefs) ? $this->prefs['mail_signature'] : $mailOptions->getSignature());
2270  $mailOptions->setIncomingType(array_key_exists('mail_incoming_type', $this->prefs) ? (int) $this->prefs['mail_incoming_type'] : $mailOptions->getIncomingType());
2271  $mailOptions->updateOptions();
2272  }
2273  }
2274 
2275  private function getCDataWithoutTags(): string
2276  {
2277  return $this->stripTags($this->cdata);
2278  }
2279 
2280  private function stripTags(string $string): string
2281  {
2282  return $this->refinery->string()->stripTags()->transform($string);
2283  }
2284 }
Class ilObjRole.
ilRecommendedContentManager $recommended_content_manager
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
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)
Class ChatMainBarProvider .
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)
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...
global $DIC
Definition: feed.php:28
static getUserIdByLogin(string $a_login)
$messages
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: xapiexit.php:22
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:67
__construct(VocabulariesInterface $vocabularies)
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.
string $key
Consumer key/client ID value.
Definition: System.php:193
header include for all ilias files.
array $localRoleCache
Cached local roles.
set(string $a_field, string $a_value)
$http
Definition: raiseError.php:7
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.
array $protocol
The variable holds the protocol of the import.
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
Class ilAccountMail.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
string $reason
Error message for last request processed.
Definition: System.php:102
getParentRoleIds(int $a_role_id)
Get array of parent role ids from cache.
$message
Definition: xapiexit.php:32
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.