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