ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilObjUser.php
Go to the documentation of this file.
1 <?php
2 
24 use ILIAS\Data\DateFormat\Factory as DateFormatFactory;
27 use ILIAS\Export\ExportHandler\Factory as ExportFactory;
28 
35 class ilObjUser extends ilObject
36 {
37  public const NO_AVATAR_RID = '-';
38  public const PASSWD_PLAIN = 'plain';
39  public const PASSWD_CRYPTED = 'crypted';
40  protected string $ext_account = '';
41  protected string $time_limit_message = '';
42  protected bool $time_limit_unlimited = false;
43  protected ?int $time_limit_until = null;
44  protected ?int $time_limit_from = null;
45  protected ?int $time_limit_owner = null;
46  protected string $last_login = '';
47 
48  public string $login = '';
49  protected string $passwd = ''; // password encoded in the format specified by $passwd_type
50  protected string $passwd_type = '';
51  // specifies the password format.
52  // value: ilObjUser::PASSWD_PLAIN or ilObjUser::PASSWD_CRYPTED.
53  // Differences between password format in class ilObjUser and
54  // in table usr_data:
55  // Class ilObjUser supports two different password types
56  // (plain and crypted) and it uses the variables $passwd
57  // and $passwd_type to store them.
58  // Table usr_data supports only two different password types
59  // (md5 and bcrypt) and it uses the columns 'passwd' and 'passwd_type' to store them.
60  // The conversion between these two storage layouts is done
61  // in the methods that perform SQL statements. All other
62  // methods work exclusively with the $passwd and $passwd_type
63  // variables.
64  protected ?string $password_encoding_type = null; // The encoding algorithm of the user's password stored in the database
65  // A salt used to encrypt the user's password
66  protected ?string $password_salt = null;
67  public string $gender = ''; // 'm' or 'f'
68  public string $utitle = ''; // user title (keep in mind, that we derive $title from object also!)
69  public string $firstname = '';
70  public string $lastname = '';
71  protected ?string $birthday = null;
72  public string $fullname = ''; // title + firstname + lastname in one string
73  public string $institution = '';
74  public string $department = '';
75  public string $street = '';
76  public string $city = '';
77  public string $zipcode = '';
78  public string $country = '';
79  public string $sel_country = '';
80  public string $phone_office = '';
81  public string $phone_home = '';
82  public string $phone_mobile = '';
83  public string $fax = '';
84  public string $email = '';
85  protected ?string $second_email = null;
86  public string $hobby = '';
87  public string $matriculation = '';
88  public string $referral_comment = '';
89  public ?string $approve_date = null;
90  public ?string $agree_date = null;
91  public int $active = 0;
92  public string $client_ip = ''; // client ip to check before login
93  public ?string $auth_mode = null; // authentication mode
94  public ?string $latitude = null;
95  public ?string $longitude = null;
96  public ?string $loc_zoom = null;
97  public int $last_password_change_ts = 0;
98  protected bool $passwd_policy_reset = false;
99  public int $login_attempts = 0;
100  public array $user_defined_data = []; // Missing array type.
102  protected array $oldPrefs = [];
104  public array $prefs = [];
105  public string $skin = '';
106  protected static array $personal_image_cache = [];
107  protected ?string $inactivation_date = null;
108  private bool $is_self_registered = false; // flag for self registered users
109  protected string $org_units = ''; // ids of assigned org-units, comma seperated
111  protected array $interests_general = [];
113  protected array $interests_help_offered = [];
115  protected array $interests_help_looking = [];
116  protected string $last_profile_prompt = ''; // timestamp
117  protected string $first_login = ''; // timestamp
118  protected bool $profile_incomplete = false;
119  protected ?string $avatar_rid = null;
120  protected \ILIAS\FileDelivery\Delivery\StreamDelivery $delivery;
121  protected DateFormatFactory $date_format_factory;
123  private Services $irss;
124 
125  public function __construct(
126  int $a_user_id = 0,
127  bool $a_call_by_reference = false
128  ) {
129  global $DIC;
130 
131  $this->type = 'usr';
132  parent::__construct($a_user_id, $a_call_by_reference);
133 
134  $this->cron_delete_user_reminder_mail = new ilCronDeleteInactiveUserReminderMail($this->db);
135  $this->irss = $DIC->resourceStorage();
136  $this->auth_mode = 'default';
137  $this->passwd_type = self::PASSWD_PLAIN;
138  if ($a_user_id > 0) {
139  $this->setId($a_user_id);
140  $this->read();
141  } else {
142  $this->prefs = [];
143  $this->prefs['language'] = $this->ilias->ini->readVariable('language', 'default');
144  $this->skin = $this->ilias->ini->readVariable('layout', 'skin');
145  $this->prefs['skin'] = $this->skin;
146  $this->prefs['style'] = $this->ilias->ini->readVariable('layout', 'style');
147  }
148 
149  $this->app_event_handler = $DIC['ilAppEventHandler'];
150  $this->date_format_factory = (new DataFactory())->dateFormat();
151  $this->delivery = $DIC->fileDelivery()->delivery();
152  }
153 
159  public function read(): void
160  {
161  global $DIC;
162 
163  $ilErr = $DIC['ilErr'];
164  $ilDB = $this->db;
165 
166  $r = $ilDB->queryF('SELECT * FROM usr_data ' .
167  'WHERE usr_id= %s', ['integer'], [$this->id]);
168 
169  if ($data = $ilDB->fetchAssoc($r)) {
170  // convert password storage layout used by table usr_data into
171  // storage layout used by class ilObjUser
172  $data['passwd_type'] = self::PASSWD_CRYPTED;
173 
174  // this assign must not be set via $this->assignData($data)
175  // because this method will be called on profile updates and
176  // would set this values to 0, because they arent posted from form
177  $this->setLastPasswordChangeTS($data['last_password_change']);
178  $this->setLoginAttempts($data['login_attempts']);
179  $this->setPasswordPolicyResetStatus((bool) $data['passwd_policy_reset']);
180 
181  // fill member vars in one shot
182  $this->assignData($data);
183 
184  //get userpreferences from usr_pref table
185  $this->readPrefs();
186 
187  if (!isset($this->prefs['language']) || $this->prefs['language'] === '') {
188  $this->prefs['language'] = $this->oldPrefs['language'] ?? '';
189  }
190 
191  if (
192  !isset($this->prefs['skin']) || $this->prefs['skin'] === '' ||
193  !ilStyleDefinition::skinExists($this->prefs['skin'])
194  ) {
195  $this->prefs['skin'] = $this->oldPrefs['skin'] ?? '';
196  }
197 
198  $this->skin = $this->prefs['skin'];
199 
200  if (
201  !isset($this->prefs['style']) ||
202  $this->prefs['style'] === '' ||
203  !ilStyleDefinition::styleExists($this->prefs['style']) ||
204  (
205  !ilStyleDefinition::skinExists($this->skin) &&
206  ilStyleDefinition::styleExistsForSkinId($this->skin, $this->prefs['style'])
207  )
208  ) {
209  //load default (css)
210  $this->prefs['skin'] = $this->ilias->ini->readVariable('layout', 'skin');
211  $this->prefs['style'] = $this->ilias->ini->readVariable('layout', 'style');
212  }
213  } else {
214  $ilErr->raiseError('<b>Error: There is no dataset with id ' .
215  $this->id . '!</b><br />class: ' . get_class($this) . '<br />Script: ' . __FILE__ .
216  '<br />Line: ' . __LINE__, $ilErr->FATAL);
217  }
218 
219  $this->readMultiTextFields();
220  $this->readUserDefinedFields();
221 
222  parent::read();
223  }
224 
225  public function getPasswordEncodingType(): ?string
226  {
228  }
229 
230  public function setPasswordEncodingType(?string $password_encryption_type): void
231  {
232  $this->password_encoding_type = $password_encryption_type;
233  }
234 
235  public function getPasswordSalt(): ?string
236  {
237  return $this->password_salt;
238  }
239 
240  public function setPasswordSalt(?string $password_salt): void
241  {
242  $this->password_salt = $password_salt;
243  }
244 
249  public function assignData(array $a_data): void
250  {
251  global $DIC;
252 
253  $ilErr = $DIC['ilErr'];
254 
255  // basic personal data
256  $this->setLogin($a_data['login'] ?? '');
257  if (!($a_data['passwd_type'] ?? false)) {
258  $ilErr->raiseError('<b>Error: passwd_type missing in function assignData(). ' .
259  $this->id . '!</b><br />class: ' . get_class($this) . '<br />Script: '
260  . __FILE__ . '<br />Line: ' . __LINE__, $ilErr->FATAL);
261  }
262  if (($a_data['passwd'] ?? '') != '********' && strlen($a_data['passwd'] ?? '')) {
263  $this->setPasswd($a_data['passwd'] ?? '', $a_data['passwd_type'] ?? '');
264  }
265 
266  $this->setGender((string) ($a_data['gender'] ?? ''));
267  $this->setUTitle((string) ($a_data['title'] ?? ''));
268  $this->setFirstname((string) ($a_data['firstname'] ?? ''));
269  $this->setLastname((string) ($a_data['lastname'] ?? ''));
270  $this->setFullname();
271  if (isset($a_data['birthday']) && is_string($a_data['birthday'])) {
272  $this->setBirthday($a_data['birthday']);
273  } else {
274  $this->setBirthday(null);
275  }
276 
277  // address data
278  $this->setInstitution((string) ($a_data['institution'] ?? ''));
279  $this->setDepartment((string) ($a_data['department'] ?? ''));
280  $this->setStreet((string) ($a_data['street'] ?? ''));
281  $this->setCity((string) ($a_data['city'] ?? ''));
282  $this->setZipcode((string) ($a_data['zipcode'] ?? ''));
283  $this->setCountry((string) ($a_data['country'] ?? ''));
284  $this->setSelectedCountry((string) ($a_data['sel_country'] ?? ''));
285  $this->setPhoneOffice((string) ($a_data['phone_office'] ?? ''));
286  $this->setPhoneHome((string) ($a_data['phone_home'] ?? ''));
287  $this->setPhoneMobile((string) ($a_data['phone_mobile'] ?? ''));
288  $this->setFax((string) ($a_data['fax'] ?? ''));
289  $this->setMatriculation((string) ($a_data['matriculation'] ?? ''));
290  $this->setEmail((string) ($a_data['email'] ?? ''));
291  $this->setSecondEmail((string) ($a_data['second_email'] ?? null));
292  $this->setHobby((string) ($a_data['hobby'] ?? ''));
293  $this->setClientIP((string) ($a_data['client_ip'] ?? ''));
294  $this->setPasswordEncodingType($a_data['passwd_enc_type'] ?? null);
295  $this->setPasswordSalt($a_data['passwd_salt'] ?? null);
296 
297  // other data
298  $this->setLatitude($a_data['latitude'] ?? null);
299  $this->setLongitude($a_data['longitude'] ?? null);
300  $this->setLocationZoom($a_data['loc_zoom'] ?? null);
301 
302  // system data
303  $this->setLastLogin((string) ($a_data['last_login'] ?? ''));
304  $this->setFirstLogin((string) ($a_data['first_login'] ?? ''));
305  $this->setLastProfilePrompt((string) ($a_data['last_profile_prompt'] ?? ''));
306  $this->setLastUpdate((string) ($a_data['last_update'] ?? ''));
307  $this->create_date = $a_data['create_date'] ?? '';
308  $this->setComment((string) ($a_data['referral_comment'] ?? ''));
309  $this->approve_date = ($a_data['approve_date'] ?? null);
310  $this->active = ($a_data['active'] ?? 0);
311  $this->agree_date = ($a_data['agree_date'] ?? null);
312 
313  $this->setInactivationDate((string) ($a_data['inactivation_date'] ?? null));
314 
315  // time limitation
316  $this->setTimeLimitOwner((int) ($a_data['time_limit_owner'] ?? 0));
317  $this->setTimeLimitUnlimited((bool) ($a_data['time_limit_unlimited'] ?? false));
318  $this->setTimeLimitFrom((int) ($a_data['time_limit_from'] ?? 0));
319  $this->setTimeLimitUntil((int) ($a_data['time_limit_until'] ?? 0));
320  $this->setTimeLimitMessage((string) ($a_data['time_limit_message'] ?? ''));
321 
322  // user profile incomplete?
323  $this->setProfileIncomplete((bool) ($a_data['profile_incomplete'] ?? false));
324 
325  //authentication
326  $this->setAuthMode((string) ($a_data['auth_mode'] ?? null));
327  $this->setExternalAccount((string) ($a_data['ext_account'] ?? ''));
328 
329  $this->setIsSelfRegistered((bool) ($a_data['is_self_registered'] ?? false));
330 
331  // Avatar
332  $this->avatar_rid = (string) ($a_data['rid'] ?? self::NO_AVATAR_RID);
333  }
334 
340  public function saveAsNew(): void
341  {
342  global $DIC;
343 
344  $ilAppEventHandler = $DIC['ilAppEventHandler'];
345 
346  $ilErr = $DIC['ilErr'];
347  $ilDB = $this->db;
348  $pw_value = '';
349 
350  switch ($this->passwd_type) {
351  case self::PASSWD_PLAIN:
352  if (strlen($this->passwd)) {
353  LocalUserPasswordManager::getInstance()->encodePassword($this, $this->passwd);
354  $pw_value = $this->getPasswd();
355  } else {
356  $pw_value = $this->passwd;
357  }
358  break;
359 
360  case self::PASSWD_CRYPTED:
361  $pw_value = $this->passwd;
362  break;
363 
364  default:
365  $ilErr->raiseError('<b>Error: passwd_type missing in function saveAsNew. ' .
366  $this->id . '!</b><br />class: ' . get_class($this) . '<br />Script: ' . __FILE__ .
367  '<br />Line: ' . __LINE__, $ilErr->FATAL);
368  }
369 
370  if (!$this->active) {
372  } else {
373  $this->setInactivationDate(null);
374  }
375 
376  $insert_array = [
377  'usr_id' => ['integer', $this->id],
378  'login' => ['text', $this->login],
379  'passwd' => ['text', $pw_value],
380  'passwd_enc_type' => ['text', $this->getPasswordEncodingType()],
381  'passwd_salt' => ['text', $this->getPasswordSalt()],
382  'firstname' => ['text', $this->firstname],
383  'lastname' => ['text', $this->lastname],
384  'title' => ['text', $this->utitle],
385  'gender' => ['text', $this->gender],
386  'email' => ['text', trim($this->email ?? '')],
387  'second_email' => ['text', trim($this->second_email ?? '')],
388  'hobby' => ['text', $this->hobby],
389  'institution' => ['text', $this->institution],
390  'department' => ['text', $this->department],
391  'street' => ['text', $this->street],
392  'city' => ['text', $this->city],
393  'zipcode' => ['text', $this->zipcode],
394  'country' => ['text', $this->country],
395  'sel_country' => ['text', $this->sel_country],
396  'phone_office' => ['text', $this->phone_office],
397  'phone_home' => ['text', $this->phone_home],
398  'phone_mobile' => ['text', $this->phone_mobile],
399  'fax' => ['text', $this->fax],
400  'birthday' => ['date', $this->getBirthday()],
401  'last_login' => ['timestamp', null],
402  'first_login' => ['timestamp', null],
403  'last_profile_prompt' => ['timestamp', null],
404  'last_update' => ['timestamp', ilUtil::now()],
405  'create_date' => ['timestamp', ilUtil::now()],
406  'referral_comment' => ['text', $this->referral_comment],
407  'matriculation' => ['text', $this->matriculation],
408  'client_ip' => ['text', $this->client_ip],
409  'approve_date' => ['timestamp', $this->approve_date],
410  'agree_date' => ['timestamp', $this->agree_date],
411  'active' => ['integer', $this->active],
412  'time_limit_unlimited' => ['integer', $this->getTimeLimitUnlimited()],
413  'time_limit_until' => ['integer', $this->getTimeLimitUntil()],
414  'time_limit_from' => ['integer', $this->getTimeLimitFrom()],
415  'time_limit_owner' => ['integer', $this->getTimeLimitOwner()],
416  'auth_mode' => ['text', $this->getAuthMode()],
417  'ext_account' => ['text', $this->getExternalAccount()],
418  'profile_incomplete' => ['integer', $this->getProfileIncomplete()],
419  'latitude' => ['text', $this->latitude],
420  'longitude' => ['text', $this->longitude],
421  'loc_zoom' => ['integer', (int) $this->loc_zoom],
422  'last_password_change' => ['integer', $this->last_password_change_ts],
423  'passwd_policy_reset' => ['integer', (int) $this->passwd_policy_reset],
424  'inactivation_date' => ['timestamp', $this->inactivation_date],
425  'is_self_registered' => ['integer', (int) $this->is_self_registered],
426  ];
427  $ilDB->insert('usr_data', $insert_array);
428 
429  $this->updateMultiTextFields(true);
430  $this->updateUserDefinedFields();
431 
432  // CREATE ENTRIES FOR MAIL BOX
433  $mbox = new ilMailbox($this->id);
434  $mbox->createDefaultFolder();
435 
436  $mail_options = new ilMailOptions($this->id);
437  $mail_options->createMailOptionsEntry();
438 
439  $ilAppEventHandler->raise(
440  'components/ILIAS/User',
441  'afterCreate',
442  ['user_obj' => $this]
443  );
444  }
445 
446  public function update(): bool
447  {
448  global $DIC;
449 
450  $ilErr = $DIC['ilErr'];
451  $ilDB = $this->db;
452  $ilAppEventHandler = $this->app_event_handler;
453 
454  $this->syncActive();
455 
456  if ($this->getStoredActive($this->id) && !$this->active) {
458  } elseif ($this->active) {
459  $this->setInactivationDate(null);
460  }
461 
462  $update_array = [
463  'gender' => ['text', $this->gender],
464  'title' => ['text', $this->utitle],
465  'firstname' => ['text', substr($this->firstname, 0, 128)],
466  'lastname' => ['text', substr($this->lastname, 0, 128)],
467  'email' => ['text', substr(trim($this->email), 0, 128)],
468  'second_email' => ['text', trim($this->second_email ?? '')],
469  'birthday' => ['date', $this->getBirthday()],
470  'hobby' => ['text', $this->hobby],
471  'institution' => ['text', $this->institution],
472  'department' => ['text', $this->department],
473  'street' => ['text', $this->street],
474  'city' => ['text', $this->city],
475  'zipcode' => ['text', $this->zipcode],
476  'country' => ['text', $this->country],
477  'sel_country' => ['text', $this->sel_country],
478  'phone_office' => ['text', $this->phone_office],
479  'phone_home' => ['text', $this->phone_home],
480  'phone_mobile' => ['text', $this->phone_mobile],
481  'fax' => ['text', $this->fax],
482  'referral_comment' => ['text', $this->referral_comment],
483  'matriculation' => ['text', $this->matriculation],
484  'client_ip' => ['text', $this->client_ip],
485  'approve_date' => ['timestamp', $this->approve_date],
486  'active' => ['integer', $this->active],
487  'time_limit_unlimited' => ['integer', $this->getTimeLimitUnlimited()],
488  'time_limit_until' => ['integer', $this->getTimeLimitUntil()],
489  'time_limit_from' => ['integer', $this->getTimeLimitFrom()],
490  'time_limit_owner' => ['integer', $this->getTimeLimitOwner()],
491  'time_limit_message' => ['integer', $this->getTimeLimitMessage()],
492  'profile_incomplete' => ['integer', $this->getProfileIncomplete()],
493  'auth_mode' => ['text', $this->getAuthMode()],
494  'ext_account' => ['text', $this->getExternalAccount()],
495  'latitude' => ['text', $this->latitude],
496  'longitude' => ['text', $this->longitude],
497  'loc_zoom' => ['integer', (int) $this->loc_zoom],
498  'login_attempts' => ['integer', $this->login_attempts],
499  'last_password_change' => ['integer', $this->last_password_change_ts],
500  'passwd_policy_reset' => ['integer', $this->passwd_policy_reset],
501  'last_update' => ['timestamp', ilUtil::now()],
502  'inactivation_date' => ['timestamp', $this->inactivation_date],
503  'reg_hash' => ['text', null],
504  'rid' => [
505  'text',
506  ($this->avatar_rid ?? self::NO_AVATAR_RID)
507  ],
508  ];
509 
510  if ($this->agree_date === null || (is_string($this->agree_date) && strtotime($this->agree_date) !== false)) {
511  $update_array['agree_date'] = ['timestamp', $this->agree_date];
512  }
513  switch ($this->passwd_type) {
514  case self::PASSWD_PLAIN:
515  if (strlen($this->passwd)) {
516  LocalUserPasswordManager::getInstance()->encodePassword($this, $this->passwd);
517  $update_array['passwd'] = ['text', $this->getPasswd()];
518  } else {
519  $update_array['passwd'] = ['text', $this->passwd];
520  }
521  break;
522 
523  case self::PASSWD_CRYPTED:
524  $update_array['passwd'] = ['text', $this->passwd];
525  break;
526 
527  default:
528  $ilErr->raiseError('<b>Error: passwd_type missing in function update()' . $this->id . '!</b><br />class: ' .
529  get_class($this) . '<br />Script: ' . __FILE__ . '<br />Line: ' . __LINE__, $ilErr->FATAL);
530  }
531 
532  $update_array['passwd_enc_type'] = ['text', $this->getPasswordEncodingType()];
533  $update_array['passwd_salt'] = ['text', $this->getPasswordSalt()];
534 
535  $ilDB->update('usr_data', $update_array, ['usr_id' => ['integer', $this->id]]);
536 
537  $this->updateMultiTextFields();
538 
539  $this->writePrefs();
540 
541  // update user defined fields
542  $this->updateUserDefinedFields();
543 
544  parent::update();
545  $this->updateOwner();
546 
547  $this->read();
548 
549  $ilAppEventHandler->raise(
550  'components/ILIAS/User',
551  'afterUpdate',
552  ['user_obj' => $this]
553  );
554 
555  return true;
556  }
557 
561  public function writeAccepted(): void
562  {
563  $ilDB = $this->db;
564  $ilDB->manipulateF('UPDATE usr_data SET agree_date = ' . $ilDB->now() .
565  ' WHERE usr_id = %s', ['integer'], [$this->getId()]);
566  }
567 
568  private static function _lookup(
569  int $a_user_id,
570  string $a_field
571  ): ?string {
572  global $DIC;
573 
574  $ilDB = $DIC->database();
575 
576  $res = $ilDB->queryF(
577  'SELECT ' . $a_field . ' FROM usr_data WHERE usr_id = %s',
578  ['integer'],
579  [$a_user_id]
580  );
581 
582  while ($set = $ilDB->fetchAssoc($res)) {
583  return $set[$a_field];
584  }
585  return null;
586  }
587 
588  public static function _lookupFullname(int $a_user_id): string
589  {
590  global $DIC;
591 
592  $fullname = '';
593  $ilDB = $DIC['ilDB'];
594 
595  $set = $ilDB->queryF(
596  'SELECT title, firstname, lastname FROM usr_data WHERE usr_id = %s',
597  ['integer'],
598  [$a_user_id]
599  );
600 
601  if ($rec = $ilDB->fetchAssoc($set)) {
602  if ($rec['title']) {
603  $fullname = $rec['title'] . ' ';
604  }
605  if ($rec['firstname']) {
606  $fullname .= $rec['firstname'] . ' ';
607  }
608  if ($rec['lastname']) {
609  $fullname .= $rec['lastname'];
610  }
611  }
612  return $fullname;
613  }
614 
615  public static function _lookupEmail(int $a_user_id): string
616  {
617  return self::_lookup($a_user_id, 'email') ?? '';
618  }
619 
620  public static function _lookupGender(int $a_user_id): string
621  {
622  return (string) self::_lookup($a_user_id, 'gender') ?? '';
623  }
624 
625  public static function _lookupClientIP(int $a_user_id): string
626  {
627  return self::_lookup($a_user_id, 'client_ip') ?? '';
628  }
629 
634  public static function _lookupName(int $a_user_id): array
635  {
636  global $DIC;
637 
638  $ilDB = $DIC['ilDB'];
639 
640  $res = $ilDB->queryF(
641  'SELECT firstname, lastname, title, login FROM usr_data WHERE usr_id = %s',
642  ['integer'],
643  [$a_user_id]
644  );
645  if ($user_rec = $ilDB->fetchAssoc($res)) {
646  return ['user_id' => $a_user_id,
647  'firstname' => $user_rec['firstname'],
648  'lastname' => $user_rec['lastname'],
649  'title' => $user_rec['title'],
650  'login' => $user_rec['login']
651  ];
652  }
653  return ['user_id' => 0,
654  'firstname' => '',
655  'lastname' => '',
656  'title' => '',
657  'login' => ''
658  ];
659  }
660 
665  public static function _lookupFields(int $a_user_id): array // Missing array type.
666  {
667  global $DIC;
668 
669  $ilDB = $DIC['ilDB'];
670 
671  $res = $ilDB->queryF(
672  'SELECT * FROM usr_data WHERE usr_id = %s',
673  ['integer'],
674  [$a_user_id]
675  );
676  $user_rec = $ilDB->fetchAssoc($res);
677  return $user_rec;
678  }
679 
680  public static function _lookupLogin(int $a_user_id): string
681  {
682  return (string) self::_lookup($a_user_id, 'login') ?? '';
683  }
684 
685  public static function _lookupExternalAccount(int $a_user_id): string
686  {
687  return (string) self::_lookup($a_user_id, 'ext_account') ?? '';
688  }
689 
694  public static function _lookupId($a_user_str)
695  {
696  global $DIC;
697 
698  $ilDB = $DIC['ilDB'];
699 
700  if (!is_array($a_user_str)) {
701  $res = $ilDB->queryF(
702  'SELECT usr_id FROM usr_data WHERE login = %s',
703  ['text'],
704  [$a_user_str]
705  );
706 
707  $user_rec = $ilDB->fetchAssoc($res);
708  if (is_array($user_rec)) {
709  return (int) $user_rec['usr_id'];
710  }
711 
712  return null;
713  }
714 
715  $set = $ilDB->query(
716  'SELECT usr_id FROM usr_data ' .
717  ' WHERE ' . $ilDB->in('login', $a_user_str, false, 'text')
718  );
719 
720  $ids = [];
721  while ($rec = $ilDB->fetchAssoc($set)) {
722  $ids[] = (int) $rec['usr_id'];
723  }
724 
725  return $ids;
726  }
727 
728  public static function _lookupLastLogin(int $a_user_id): string
729  {
730  return self::_lookup($a_user_id, 'last_login') ?? '';
731  }
732 
733  public static function _lookupFirstLogin(int $a_user_id): string
734  {
735  return self::_lookup($a_user_id, 'first_login') ?? '';
736  }
737 
738 
743  public function refreshLogin(): void
744  {
745  $ilDB = $this->db;
746 
747  $ilDB->manipulateF(
748  'UPDATE usr_data SET ' .
749  'last_login = ' . $ilDB->now() .
750  ' WHERE usr_id = %s',
751  ['integer'],
752  [$this->id]
753  );
754 
755  if ($this->getFirstLogin() == '') {
756  $ilDB->manipulateF(
757  'UPDATE usr_data SET ' .
758  'first_login = ' . $ilDB->now() .
759  ' WHERE usr_id = %s',
760  ['integer'],
761  [$this->id]
762  );
763  $this->app_event_handler->raise(
764  'components/ILIAS/User',
765  'firstLogin',
766  ['user_obj' => $this]
767  );
768  }
769  }
770 
771 
780  public function resetPassword(
781  string $raw,
782  string $raw_retype
783  ): bool {
784  $ilDB = $this->db;
785 
786  if (func_num_args() != 2) {
787  return false;
788  }
789 
790  if (!isset($raw) || !isset($raw_retype)) {
791  return false;
792  }
793 
794  if ($raw != $raw_retype) {
795  return false;
796  }
797 
798  LocalUserPasswordManager::getInstance()->encodePassword($this, $raw);
799 
800  $ilDB->manipulateF(
801  'UPDATE usr_data
802  SET passwd = %s, passwd_enc_type = %s, passwd_salt = %s
803  WHERE usr_id = %s',
804  ['text', 'text', 'text', 'integer'],
805  [$this->getPasswd(), $this->getPasswordEncodingType(), $this->getPasswordSalt(), $this->getId()]
806  );
807 
808  return true;
809  }
810 
814  public static function _doesLoginnameExistInHistory(string $a_login): bool
815  {
816  global $DIC;
817 
818  $ilDB = $DIC->database();
819 
820  $res = $ilDB->queryF(
821  '
822  SELECT * FROM loginname_history
823  WHERE login = %s',
824  ['text'],
825  [$a_login]
826  );
827 
828  return (bool) $ilDB->fetchAssoc($res);
829  }
830 
837  public static function _getLastHistoryDataByUserId(int $a_usr_id): array
838  {
839  global $DIC;
840 
841  $ilDB = $DIC['ilDB'];
842 
843  $ilDB->setLimit(1, 0);
844  $res = $ilDB->queryF(
845  '
846  SELECT login, history_date FROM loginname_history
847  WHERE usr_id = %s ORDER BY history_date DESC',
848  ['integer'],
849  [$a_usr_id]
850  );
851  $row = $ilDB->fetchAssoc($res);
852  if (!is_array($row) || !count($row)) {
853  throw new ilUserException('');
854  }
855 
856  return [
857  $row['login'], $row['history_date']
858  ];
859  }
860 
868  public function updateLogin(string $a_login): bool
869  {
870  global $DIC;
871 
872  $ilDB = $this->db;
873  $ilSetting = $DIC['ilSetting'];
874  $lng = $DIC->language();
875 
876  if (func_num_args() != 1) {
877  return false;
878  }
879 
880  if (!isset($a_login)) {
881  return false;
882  }
883 
884  $former_login = self::_lookupLogin($this->getId());
885 
886  // Update not necessary
887  if (0 == strcmp($a_login, $former_login)) {
888  return false;
889  }
890 
891  try {
892  $last_history_entry = self::_getLastHistoryDataByUserId($this->getId());
893  } catch (ilUserException $e) {
894  $last_history_entry = null;
895  }
896 
897  // throw exception if the desired loginame is already in history and it is not allowed to reuse it
898  if ((int) $ilSetting->get('allow_change_loginname') &&
899  (int) $ilSetting->get('reuse_of_loginnames') == 0 &&
900  self::_doesLoginnameExistInHistory($a_login)) {
901  throw new ilUserException($lng->txt('loginname_already_exists'));
902  } elseif ((int) $ilSetting->get('allow_change_loginname') &&
903  (int) $ilSetting->get('loginname_change_blocking_time') &&
904  is_array($last_history_entry) &&
905  $last_history_entry[1] + (int) $ilSetting->get('loginname_change_blocking_time') > time()) {
906  throw new ilUserException(
907  sprintf(
908  $lng->txt('changing_loginname_not_possible_info'),
910  new ilDateTime($last_history_entry[1], IL_CAL_UNIX)
911  ),
913  new ilDateTime(($last_history_entry[1] + (int) $ilSetting->get('loginname_change_blocking_time')), IL_CAL_UNIX)
914  )
915  )
916  );
917  } else {
918  // log old loginname in history
919  if ((int) $ilSetting->get('allow_change_loginname') &&
920  (int) $ilSetting->get('create_history_loginname')) {
921  self::_writeHistory($this->getId(), $former_login);
922  }
923 
924  //update login
925  $this->login = $a_login;
926 
927  $ilDB->manipulateF(
928  '
929  UPDATE usr_data
930  SET login = %s
931  WHERE usr_id = %s',
932  ['text', 'integer'],
933  [$this->getLogin(), $this->getId()]
934  );
935  }
936 
937  return true;
938  }
939 
940  public function writePref(
941  string $a_keyword,
942  string $a_value
943  ): void {
944  self::_writePref($this->id, $a_keyword, $a_value);
945  $this->setPref($a_keyword, $a_value);
946  }
947 
948  public function deletePref(string $a_keyword): void
949  {
950  self::_deletePref($this->getId(), $a_keyword);
951  }
952 
953  public static function _deletePref(int $a_user_id, string $a_keyword): void
954  {
955  global $DIC;
956 
957  $ilDB = $DIC->database();
958 
959  $ilDB->manipulateF(
960  'DELETE FROM usr_pref WHERE usr_id = %s AND keyword = %s',
961  ['integer', 'text'],
962  [$a_user_id, $a_keyword]
963  );
964  }
965 
969  public static function _deleteAllPref(int $a_user_id): void
970  {
971  global $DIC;
972 
973  $ilDB = $DIC->database();
974 
975  $ilDB->manipulateF(
976  'DELETE FROM usr_pref WHERE usr_id = %s',
977  ['integer'],
978  [$a_user_id]
979  );
980  }
981 
982  public static function _writePref(
983  int $a_usr_id,
984  string $a_keyword,
985  string $a_value
986  ): void {
987  global $DIC;
988 
989  $ilDB = $DIC->database();
990  $ilDB->replace(
991  'usr_pref',
992  [
993  'usr_id' => ['integer', $a_usr_id],
994  'keyword' => ['text', $a_keyword],
995  ],
996  [
997  'value' => ['text',$a_value]
998  ]
999  );
1000  }
1001 
1002  public function writePrefs(): void
1003  {
1004  self::_deleteAllPref($this->id);
1005  foreach ($this->prefs as $keyword => $value) {
1006  self::_writePref($this->id, $keyword, (string) $value);
1007  }
1008  }
1009 
1010  public function getTimeZone(): string
1011  {
1012  if ($tz = $this->getPref('user_tz')) {
1013  return $tz;
1014  } else {
1015  $settings = ilCalendarSettings::_getInstance();
1016  return $settings->getDefaultTimeZone();
1017  }
1018  }
1019 
1020  public function getTimeFormat(): string
1021  {
1022  if ($format = $this->getPref('time_format')) {
1023  return $format;
1024  } else {
1025  $settings = ilCalendarSettings::_getInstance();
1026  return $settings->getDefaultTimeFormat();
1027  }
1028  }
1029 
1030  public function getDateFormat(): DateFormat
1031  {
1032  if (!($format = $this->getPref('date_format'))) {
1033  $settings = ilCalendarSettings::_getInstance();
1034  $format = $settings->getDefaultDateFormat();
1035  }
1036 
1037  switch ($format) {
1039  return $this->date_format_factory->germanShort();
1040 
1042  return $this->date_format_factory->americanShort();
1043 
1045  default:
1046  return $this->date_format_factory->standard();
1047  }
1048  }
1049 
1050  public function getDateTimeFormat(): DateFormat
1051  {
1053  return $this->date_format_factory->withTime24($this->getDateFormat());
1054  }
1055  return $this->date_format_factory->withTime12($this->getDateFormat());
1056  }
1057 
1058  public function setPref(string $a_keyword, ?string $a_value): void
1059  {
1060  if ($a_keyword != '') {
1061  $this->prefs[$a_keyword] = $a_value;
1062  }
1063  }
1064 
1065  public function getPref(string $a_keyword): ?string
1066  {
1067  return $this->prefs[$a_keyword] ?? null;
1068  }
1069 
1070  public function existsPref(string $a_keyword): bool
1071  {
1072  return (array_key_exists($a_keyword, $this->prefs));
1073  }
1074 
1075  public static function _lookupPref(
1076  int $a_usr_id,
1077  string $a_keyword
1078  ): ?string {
1079  global $DIC;
1080 
1081  $ilDB = $DIC['ilDB'];
1082 
1083  $query = 'SELECT * FROM usr_pref WHERE usr_id = ' . $ilDB->quote($a_usr_id, 'integer') . ' ' .
1084  'AND keyword = ' . $ilDB->quote($a_keyword, 'text');
1085  $res = $ilDB->query($query);
1086 
1087  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1088  return $row->value;
1089  }
1090  return null;
1091  }
1092 
1093  public function readPrefs(): void
1094  {
1095  if (is_array($this->prefs)) {
1096  $this->oldPrefs = $this->prefs;
1097  }
1098  $this->prefs = self::_getPreferences($this->id);
1099  }
1100 
1101  public function delete(): bool
1102  {
1103  global $DIC;
1104 
1105  $rbacadmin = $DIC->rbac()->admin();
1106  $ilDB = $this->db;
1107 
1108  $ilAppEventHandler = $DIC['ilAppEventHandler'];
1109  $ilAppEventHandler->raise(
1110  'Services/User',
1111  'deleteUser',
1112  ['usr_id' => $this->getId()]
1113  );
1114 
1115  // deassign from ldap groups
1117  $mapping->deleteUser($this->getId());
1118 
1119  // remove mailbox / update sent mails
1120  $mailbox = new ilMailbox($this->getId());
1121  $mailbox->delete();
1122  $mailbox->updateMailsOfDeletedUser($this->getLogin());
1123 
1124  // delete block settings
1126 
1127  // delete user_account
1128  $ilDB->manipulateF(
1129  'DELETE FROM usr_data WHERE usr_id = %s',
1130  ['integer'],
1131  [$this->getId()]
1132  );
1133 
1134  $this->deleteMultiTextFields();
1135 
1136  // delete user_prefs
1137  self::_deleteAllPref($this->getId());
1138 
1139  $this->removeUserPicture(false); // #8597
1140 
1141  // delete user_session
1143 
1144  // remove user from rbac
1145  $rbacadmin->removeUser($this->getId());
1146 
1147  // remove bookmarks
1148  // TODO: move this to class.ilBookmarkFolder
1149  $q = 'DELETE FROM bookmark_tree WHERE tree = ' .
1150  $ilDB->quote($this->getId(), 'integer');
1151  $ilDB->manipulate($q);
1152 
1153  $q = 'DELETE FROM bookmark_data WHERE user_id = ' .
1154  $ilDB->quote($this->getId(), 'integer');
1155  $ilDB->manipulate($q);
1156 
1157  // Delete crs entries
1158  ilObjCourse::_deleteUser($this->getId());
1159 
1160  // Delete user tracking
1162 
1164 
1165  // Delete Tracking data SCORM 2004 RTE
1167 
1168  // Delete Tracking data SCORM 1.2 RTE
1170 
1171  // remove all notifications
1173 
1174  // remove portfolios
1176 
1177  // remove workspace
1178  $tree = new ilWorkspaceTree($this->getId());
1179  $tree->cascadingDelete();
1180 
1181  // remove reminder entries
1182  $this->cron_delete_user_reminder_mail->removeSingleUserFromTable($this->getId());
1183 
1184  // badges
1186 
1187  // remove org unit assignments
1188  $ilOrgUnitUserAssignmentQueries = ilOrgUnitUserAssignmentQueries::getInstance();
1189  $ilOrgUnitUserAssignmentQueries->deleteAllAssignmentsOfUser($this->getId());
1190 
1191  // Delete user defined field entries
1193 
1194  // Delete clipboard entries
1195  $this->clipboardDeleteAll();
1196 
1197  // Reset owner
1198  $this->resetOwner();
1199 
1200  // delete object data
1201  parent::delete();
1202  return true;
1203  }
1204 
1210  public function setFullname(): void
1211  {
1212  $this->fullname = ($this->utitle != '')
1213  ? $this->utitle . ' '
1214  : '';
1215  $this->fullname .= $this->firstname . ' ';
1216  $this->fullname .= $this->lastname;
1217  }
1218 
1231  public function getFullname(int $a_max_strlen = 0): string
1232  {
1233  if (!$a_max_strlen) {
1234  return ilUtil::stripSlashes($this->fullname);
1235  }
1236 
1237  if (strlen($this->fullname) <= $a_max_strlen) {
1238  return ilUtil::stripSlashes($this->fullname);
1239  }
1240 
1241  if ((strlen($this->utitle) + strlen($this->lastname) + 4) <= $a_max_strlen) {
1242  return ilUtil::stripSlashes($this->utitle . ' ' . substr($this->firstname, 0, 1) . '. ' . $this->lastname);
1243  }
1244 
1245  if ((strlen($this->firstname) + strlen($this->lastname) + 1) <= $a_max_strlen) {
1246  return ilUtil::stripSlashes($this->firstname . ' ' . $this->lastname);
1247  }
1248 
1249  if ((strlen($this->lastname) + 3) <= $a_max_strlen) {
1250  return ilUtil::stripSlashes(substr($this->firstname, 0, 1) . '. ' . $this->lastname);
1251  }
1252 
1253  return ilUtil::stripSlashes(substr($this->lastname, 0, $a_max_strlen));
1254  }
1255 
1256  public function setLogin(string $a_str): void
1257  {
1258  $this->login = $a_str;
1259  }
1260 
1261  public function getLogin(): string
1262  {
1263  return $this->login;
1264  }
1265 
1266  public function setPasswd(
1267  string $a_str,
1268  string $a_type = ilObjUser::PASSWD_PLAIN
1269  ): void {
1270  $this->passwd = $a_str;
1271  $this->passwd_type = $a_type;
1272  }
1273 
1277  public function getPasswd(): string
1278  {
1279  return $this->passwd;
1280  }
1281 
1285  public function getPasswdType(): string
1286  {
1287  return $this->passwd_type;
1288  }
1289 
1290  public function setGender(string $a_str): void
1291  {
1292  $this->gender = substr($a_str, -1);
1293  }
1294 
1295  public function getGender(): string
1296  {
1297  return $this->gender;
1298  }
1299 
1305  public function setUTitle(string $a_str): void
1306  {
1307  $this->utitle = $a_str;
1308  }
1309 
1310  public function getUTitle(): string
1311  {
1312  return $this->utitle;
1313  }
1314 
1315  public function setFirstname(string $a_str): void
1316  {
1317  $this->firstname = $a_str;
1318  }
1319 
1320  public function getFirstname(): string
1321  {
1322  return $this->firstname;
1323  }
1324 
1325  public function setLastname(string $a_str): void
1326  {
1327  $this->lastname = $a_str;
1328  }
1329 
1330  public function getLastname(): string
1331  {
1332  return $this->lastname;
1333  }
1334 
1335  public function setInstitution(string $a_str): void
1336  {
1337  $this->institution = $a_str;
1338  }
1339 
1340  public function getInstitution(): string
1341  {
1342  return $this->institution;
1343  }
1344 
1345  public function setDepartment(string $a_str): void
1346  {
1347  $this->department = $a_str;
1348  }
1349 
1350  public function getDepartment(): string
1351  {
1352  return $this->department;
1353  }
1354 
1355  public function setStreet(string $a_str): void
1356  {
1357  $this->street = $a_str;
1358  }
1359 
1360  public function getStreet(): string
1361  {
1362  return $this->street;
1363  }
1364 
1365  public function setCity(string $a_str): void
1366  {
1367  $this->city = $a_str;
1368  }
1369 
1370  public function getCity(): string
1371  {
1372  return $this->city;
1373  }
1374 
1375  public function setZipcode(string $a_str): void
1376  {
1377  $this->zipcode = $a_str;
1378  }
1379 
1380  public function getZipcode(): string
1381  {
1382  return $this->zipcode;
1383  }
1384 
1385  public function setCountry(string $a_str): void
1386  {
1387  $this->country = $a_str;
1388  }
1389 
1390  public function getCountry(): string
1391  {
1392  return $this->country;
1393  }
1394 
1398  public function setSelectedCountry(string $a_val): void
1399  {
1400  $this->sel_country = $a_val;
1401  }
1402 
1406  public function getSelectedCountry(): string
1407  {
1408  return $this->sel_country;
1409  }
1410 
1411  public function setPhoneOffice(string $a_str): void
1412  {
1413  $this->phone_office = $a_str;
1414  }
1415 
1416  public function getPhoneOffice(): string
1417  {
1418  return $this->phone_office;
1419  }
1420 
1421  public function setPhoneHome(string $a_str): void
1422  {
1423  $this->phone_home = $a_str;
1424  }
1425 
1426  public function getPhoneHome(): string
1427  {
1428  return $this->phone_home;
1429  }
1430 
1431  public function setPhoneMobile(string $a_str): void
1432  {
1433  $this->phone_mobile = $a_str;
1434  }
1435 
1436  public function getPhoneMobile(): string
1437  {
1438  return $this->phone_mobile;
1439  }
1440 
1441  public function setFax(string $a_str): void
1442  {
1443  $this->fax = $a_str;
1444  }
1445 
1446  public function getFax(): string
1447  {
1448  return $this->fax;
1449  }
1450 
1451  public function setClientIP(string $a_str): void
1452  {
1453  $this->client_ip = $a_str;
1454  }
1455 
1456  public function getClientIP(): string
1457  {
1458  return $this->client_ip;
1459  }
1460 
1461  public function setMatriculation(string $a_str): void
1462  {
1463  $this->matriculation = $a_str;
1464  }
1465 
1466  public function getMatriculation(): string
1467  {
1468  return $this->matriculation;
1469  }
1470 
1471  public static function lookupMatriculation(int $a_usr_id): string
1472  {
1473  global $DIC;
1474 
1475  $ilDB = $DIC['ilDB'];
1476 
1477  $query = 'SELECT matriculation FROM usr_data ' .
1478  'WHERE usr_id = ' . $ilDB->quote($a_usr_id);
1479  $res = $ilDB->query($query);
1480  $row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT);
1481  return $row->matriculation ?: '';
1482  }
1483 
1484  public function setEmail(string $a_str): void
1485  {
1486  $this->email = $a_str;
1487  }
1488 
1489  public function getEmail(): string
1490  {
1491  return $this->email;
1492  }
1493 
1494  public function getSecondEmail(): ?string
1495  {
1496  return $this->second_email;
1497  }
1498 
1499  public function setSecondEmail(?string $second_email): void
1500  {
1501  $this->second_email = $second_email;
1502  }
1503 
1504  public function setHobby(string $a_str): void
1505  {
1506  $this->hobby = $a_str;
1507  }
1508 
1509  public function getHobby(): string
1510  {
1511  return $this->hobby;
1512  }
1513 
1514  public function setLanguage(string $a_str): void
1515  {
1516  $this->setPref('language', $a_str);
1517  ilSession::clear('lang');
1518  }
1519 
1520  public function getLanguage(): string
1521  {
1522  return $this->prefs['language'];
1523  }
1524 
1525  public function setLastPasswordChangeTS(int $a_last_password_change_ts): void
1526  {
1527  $this->last_password_change_ts = $a_last_password_change_ts;
1528  }
1529 
1530  public function getLastPasswordChangeTS(): int
1531  {
1533  }
1534 
1535  public function getPasswordPolicyResetStatus(): bool
1536  {
1538  }
1539 
1540  public function setPasswordPolicyResetStatus(bool $status): void
1541  {
1542  $this->passwd_policy_reset = $status;
1543  }
1544 
1545  public static function _lookupLanguage(int $a_usr_id): string
1546  {
1547  global $DIC;
1548 
1549  $ilDB = $DIC->database();
1550  $lng = $DIC->language();
1551 
1552  $q = 'SELECT value FROM usr_pref WHERE usr_id= ' .
1553  $ilDB->quote($a_usr_id, 'integer') . ' AND keyword = ' .
1554  $ilDB->quote('language', 'text');
1555  $r = $ilDB->query($q);
1556 
1557  while ($row = $ilDB->fetchAssoc($r)) {
1558  return (string) $row['value'];
1559  }
1560  if (is_object($lng)) {
1561  return $lng->getDefaultLanguage();
1562  }
1563  return 'en';
1564  }
1565 
1566  public static function _writeExternalAccount(
1567  int $a_usr_id,
1568  string $a_ext_id
1569  ): void {
1570  global $DIC;
1571 
1572  $ilDB = $DIC['ilDB'];
1573 
1574  $ilDB->manipulateF(
1575  'UPDATE usr_data ' .
1576  ' SET ext_account = %s WHERE usr_id = %s',
1577  ['text', 'integer'],
1578  [$a_ext_id, $a_usr_id]
1579  );
1580  }
1581 
1582  public static function _writeAuthMode(int $a_usr_id, string $a_auth_mode): void
1583  {
1584  global $DIC;
1585 
1586  $ilDB = $DIC['ilDB'];
1587 
1588  $ilDB->manipulateF(
1589  'UPDATE usr_data ' .
1590  ' SET auth_mode = %s WHERE usr_id = %s',
1591  ['text', 'integer'],
1592  [$a_auth_mode, $a_usr_id]
1593  );
1594  }
1595 
1599  public function getCurrentLanguage(): string
1600  {
1601  return (string) ilSession::get('lang');
1602  }
1603 
1607  public function setCurrentLanguage(string $a_val): void
1608  {
1609  ilSession::set('lang', $a_val);
1610  }
1611 
1612  public function setLastLogin(string $a_str): void
1613  {
1614  $this->last_login = $a_str;
1615  }
1616 
1617  public function getLastLogin(): string
1618  {
1619  return $this->last_login;
1620  }
1621 
1622  public function setFirstLogin(string $a_str): void
1623  {
1624  $this->first_login = $a_str;
1625  }
1626 
1627  public function getFirstLogin(): string
1628  {
1629  return $this->first_login;
1630  }
1631 
1632  public function setLastProfilePrompt(string $a_str): void
1633  {
1634  $this->last_profile_prompt = $a_str;
1635  }
1636 
1637  public function getLastProfilePrompt(): string
1638  {
1640  }
1641 
1642  public function setLastUpdate(string $a_str): void
1643  {
1644  $this->last_update = $a_str;
1645  }
1646 
1647  public function getLastUpdate(): string
1648  {
1649  return $this->last_update;
1650  }
1651 
1652  public function setComment(string $a_str): void
1653  {
1654  $this->referral_comment = $a_str;
1655  }
1656 
1657  public function getComment(): string
1658  {
1659  return $this->referral_comment;
1660  }
1661 
1666  public function setApproveDate(?string $a_str): void
1667  {
1668  $this->approve_date = $a_str;
1669  }
1670 
1671  public function getApproveDate(): ?string
1672  {
1673  return $this->approve_date;
1674  }
1675 
1676  public function getAgreeDate(): ?string
1677  {
1678  return $this->agree_date;
1679  }
1680  public function setAgreeDate(?string $a_str): void
1681  {
1682  $this->agree_date = $a_str;
1683  }
1684 
1689  public function setActive(
1690  bool $a_active,
1691  int $a_owner = 0
1692  ): void {
1693  $this->setOwner($a_owner);
1694 
1695  if ($a_active) {
1696  $this->active = 1;
1697  $this->setApproveDate(date('Y-m-d H:i:s'));
1698  $this->setOwner($a_owner);
1699  } else {
1700  $this->active = 0;
1701  $this->setApproveDate(null);
1702  }
1703  }
1704 
1705  public function getActive(): bool
1706  {
1707  return (bool) $this->active;
1708  }
1709 
1710  public static function _lookupActive(int $a_usr_id): bool
1711  {
1712  global $DIC;
1713 
1714  $ilDB = $DIC['ilDB'];
1715 
1716  $query = 'SELECT usr_id FROM usr_data ' .
1717  'WHERE active = ' . $ilDB->quote(1, 'integer') . ' ' .
1718  'AND usr_id = ' . $ilDB->quote($a_usr_id, 'integer');
1719  $res = $ilDB->query($query);
1720  while ($res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1721  return true;
1722  }
1723  return false;
1724  }
1725 
1731  public function syncActive(): void
1732  {
1733  $storedActive = 0;
1734  if ($this->getStoredActive($this->id)) {
1735  $storedActive = 1;
1736  }
1737 
1738  $currentActive = 0;
1739  if ($this->active) {
1740  $currentActive = 1;
1741  }
1742 
1743  if ((!empty($storedActive) && empty($currentActive)) ||
1744  (empty($storedActive) && !empty($currentActive))) {
1745  $this->setActive($currentActive, self::getUserIdByLogin(self::getLoginFromAuth()));
1746  }
1747  }
1748 
1752  public function getStoredActive(int $a_id): bool
1753  {
1754  return (bool) self::_lookup($a_id, 'active');
1755  }
1756 
1757  public function setSkin(string $a_str): void
1758  {
1759  $this->skin = $a_str;
1760  }
1761 
1762  public function setTimeLimitOwner(int $a_owner): void
1763  {
1764  $this->time_limit_owner = $a_owner;
1765  }
1766 
1767  public function getTimeLimitOwner(): int
1768  {
1769  return $this->time_limit_owner ?: 7;
1770  }
1771 
1772  public function setTimeLimitFrom(?int $a_from): void
1773  {
1774  $this->time_limit_from = $a_from;
1775  }
1776 
1777  public function getTimeLimitFrom(): ?int
1778  {
1779  return $this->time_limit_from;
1780  }
1781 
1782  public function setTimeLimitUntil(?int $a_until): void
1783  {
1784  $this->time_limit_until = $a_until;
1785  }
1786 
1787  public function getTimeLimitUntil(): ?int
1788  {
1789  return $this->time_limit_until;
1790  }
1791 
1792  public function setTimeLimitUnlimited(bool $a_unlimited): void
1793  {
1794  $this->time_limit_unlimited = $a_unlimited;
1795  }
1796 
1797  public function getTimeLimitUnlimited(): bool
1798  {
1800  }
1801 
1802  public function setTimeLimitMessage(string $a_time_limit_message): void
1803  {
1804  $this->time_limit_message = $a_time_limit_message;
1805  }
1806 
1807  public function getTimeLimitMessage(): string
1808  {
1810  }
1811 
1812  public function setLoginAttempts(int $a_login_attempts): void
1813  {
1814  $this->login_attempts = $a_login_attempts;
1815  }
1816 
1817  public function getLoginAttempts(): int
1818  {
1819  return $this->login_attempts;
1820  }
1821 
1822  public function checkTimeLimit(): bool
1823  {
1824  if ($this->getTimeLimitUnlimited()) {
1825  return true;
1826  }
1827  if ($this->getTimeLimitFrom() < time() and $this->getTimeLimitUntil() > time()) {
1828  return true;
1829  }
1830  return false;
1831  }
1832 
1833  public function setProfileIncomplete(bool $a_prof_inc): void
1834  {
1835  $this->profile_incomplete = $a_prof_inc;
1836  }
1837 
1838  public function getProfileIncomplete(): bool
1839  {
1840  if ($this->id == ANONYMOUS_USER_ID) {
1841  return false;
1842  }
1844  }
1845 
1846  public function isPasswordChangeDemanded(): bool
1847  {
1848  if ($this->id == ANONYMOUS_USER_ID) {
1849  return false;
1850  }
1851 
1852  if ($this->id == SYSTEM_USER_ID) {
1853  if (
1854  LocalUserPasswordManager::getInstance()->verifyPassword($this, base64_decode('aG9tZXI=')) &&
1856  ) {
1857  return true;
1858  } else {
1859  return false;
1860  }
1861  }
1862 
1863  $security = ilSecuritySettings::_getInstance();
1864 
1865  $authModeAllowsPasswordChange = !ilAuthUtils::_needsExternalAccountByAuthMode($this->getAuthMode(true));
1866  $passwordResetOnFirstLogin = (
1867  $security->isPasswordChangeOnFirstLoginEnabled() &&
1868  $this->getLastPasswordChangeTS() == 0 && $this->is_self_registered == false
1869  );
1870  $passwordResetOnChangedPolicy = $this->getPasswordPolicyResetStatus();
1871 
1872  return ($authModeAllowsPasswordChange && ($passwordResetOnFirstLogin || $passwordResetOnChangedPolicy));
1873  }
1874 
1875  public function isPasswordExpired(): bool
1876  {
1877  if ($this->id == ANONYMOUS_USER_ID) {
1878  return false;
1879  }
1880 
1881  $security = ilSecuritySettings::_getInstance();
1882  if ($this->getLastPasswordChangeTS() > 0) {
1883  $max_pass_age = $security->getPasswordMaxAge();
1884  if ($max_pass_age > 0) {
1885  $max_pass_age_ts = ($max_pass_age * 86400);
1886  $pass_change_ts = $this->getLastPasswordChangeTS();
1887  $current_ts = time();
1888 
1889  if (($current_ts - $pass_change_ts) > $max_pass_age_ts) {
1891  return true;
1892  }
1893  }
1894  }
1895  }
1896 
1897  return false;
1898  }
1899 
1900  public function getPasswordAge(): int
1901  {
1902  $current_ts = time();
1903  $pass_change_ts = $this->getLastPasswordChangeTS();
1904  $password_age = (int) (($current_ts - $pass_change_ts) / 86400);
1905  return $password_age;
1906  }
1907 
1908  public function setLastPasswordChangeToNow(): bool
1909  {
1910  global $DIC;
1911 
1912  $ilDB = $DIC['ilDB'];
1913 
1914  $this->setLastPasswordChangeTS(time());
1915 
1916  $query = 'UPDATE usr_data SET last_password_change = %s ' .
1917  'WHERE usr_id = %s';
1918  $affected = $ilDB->manipulateF(
1919  $query,
1920  ['integer','integer'],
1921  [$this->getLastPasswordChangeTS(),$this->id]
1922  );
1923  if ($affected) {
1924  return true;
1925  } else {
1926  return false;
1927  }
1928  }
1929 
1930  public function resetLastPasswordChange(): bool
1931  {
1932  $ilDB = $this->db;
1933 
1934  $query = 'UPDATE usr_data SET last_password_change = 0 ' .
1935  'WHERE usr_id = %s';
1936  $affected = $ilDB->manipulateF(
1937  $query,
1938  ['integer'],
1939  [$this->getId()]
1940  );
1941  if ($affected) {
1942  return true;
1943  } else {
1944  return false;
1945  }
1946  }
1947 
1948  public function setLatitude(?string $a_latitude): void
1949  {
1950  $this->latitude = $a_latitude;
1951  }
1952 
1953  public function getLatitude(): ?string
1954  {
1955  return $this->latitude;
1956  }
1957 
1958  public function setLongitude(?string $a_longitude): void
1959  {
1960  $this->longitude = $a_longitude;
1961  }
1962 
1963  public function getLongitude(): ?string
1964  {
1965  return $this->longitude;
1966  }
1967 
1968  public function setLocationZoom(?int $a_locationzoom): void
1969  {
1970  $this->loc_zoom = $a_locationzoom;
1971  }
1972 
1973  public function getLocationZoom(): ?int
1974  {
1975  return $this->loc_zoom;
1976  }
1977 
1978  public function getAvatarRid(): ?string
1979  {
1980  return $this->avatar_rid;
1981  }
1982 
1983  public function setAvatarRid(?string $avatar_rid): void
1984  {
1985  $this->avatar_rid = $avatar_rid;
1986  }
1987 
1988 
1989  public static function hasActiveSession(
1990  int $a_user_id,
1991  string $a_session_id
1992  ): bool {
1993  global $DIC;
1994 
1995  $ilDB = $DIC['ilDB'];
1996 
1997  $set = $ilDB->queryf(
1998  '
1999  SELECT COUNT(*) session_count
2000  FROM usr_session WHERE user_id = %s AND expires > %s AND session_id != %s ',
2001  ['integer', 'integer', 'text'],
2002  [$a_user_id, time(), $a_session_id]
2003  );
2004  $row = $ilDB->fetchAssoc($set);
2005  return (bool) $row['session_count'];
2006  }
2007 
2011  public function checkUserId(): bool
2012  {
2013  $login = self::getLoginFromAuth();
2014  $id = self::_lookupId($login);
2015  if ($id > 0) {
2016  return $id;
2017  }
2018  return false;
2019  }
2020 
2024  private static function getLoginFromAuth(): string
2025  {
2026  $uid = $GLOBALS['DIC']['ilAuthSession']->getUserId();
2027  $login = self::_lookupLogin($uid);
2028 
2029  // BEGIN WebDAV: Strip Microsoft Domain Names from logins
2031  $login = self::toUsernameWithoutDomain($login);
2032  }
2033  return $login;
2034  }
2035 
2040  public static function toUsernameWithoutDomain(string $a_login): string
2041  {
2042  // Remove all characters including the last slash or the last backslash
2043  // in the username
2044  $pos = strrpos($a_login, '/');
2045  $pos2 = strrpos($a_login, '\\');
2046  if ($pos === false || $pos < $pos2) {
2047  $pos = $pos2;
2048  }
2049  if (is_int($pos)) {
2050  $a_login = substr($a_login, $pos + 1);
2051  }
2052  return $a_login;
2053  }
2054 
2055  /*
2056  * check to see if current user has been made active
2057  */
2058  public function isCurrentUserActive(): bool
2059  {
2060  $ilDB = $this->db;
2061 
2062  $login = self::getLoginFromAuth();
2063  $set = $ilDB->queryF(
2064  'SELECT active FROM usr_data WHERE login= %s',
2065  ['text'],
2066  [$login]
2067  );
2068  //query has got a result
2069  if ($rec = $ilDB->fetchAssoc($set)) {
2070  if ($rec['active']) {
2071  return true;
2072  }
2073  }
2074 
2075  return false;
2076  }
2077 
2078  public static function getUserIdByLogin(string $a_login): int
2079  {
2080  return (int) self::_lookupId($a_login);
2081  }
2082 
2086  public static function getUserIdsByEmail(string $a_email): array
2087  {
2088  global $DIC;
2089 
2090  $ilDB = $DIC->database();
2091 
2092  $res = $ilDB->queryF(
2093  'SELECT usr_id FROM usr_data ' .
2094  'WHERE email = %s and active = 1',
2095  ['text'],
2096  [$a_email]
2097  );
2098  $ids = [];
2099  while ($row = $ilDB->fetchObject($res)) {
2100  $ids[] = (int) $row->usr_id;
2101  }
2102 
2103  return $ids;
2104  }
2105 
2106 
2110  public static function getUserLoginsByEmail(string $a_email): array
2111  {
2112  global $DIC;
2113 
2114  $ilDB = $DIC->database();
2115 
2116  $res = $ilDB->queryF(
2117  'SELECT login FROM usr_data ' .
2118  'WHERE email = %s and active = 1',
2119  ['text'],
2120  [$a_email]
2121  );
2122  $ids = [];
2123  while ($row = $ilDB->fetchObject($res)) {
2124  $ids[] = $row->login;
2125  }
2126 
2127  return $ids;
2128  }
2129 
2130  public function getLoginByUserId(int $a_userid): ?string
2131  {
2132  $login = self::_lookupLogin($a_userid);
2133  return $login ?: null;
2134  }
2135 
2139  public static function getAllUserLogins(): array
2140  {
2144  global $DIC;
2145 
2146  $ilDB = $DIC['ilDB'];
2147 
2148  $logins = [];
2149 
2150  $res = $ilDB->query(
2151  'SELECT login FROM usr_data WHERE ' . $ilDB->in('usr_id', [ANONYMOUS_USER_ID], true, 'integer')
2152  );
2153  while ($row = $ilDB->fetchAssoc($res)) {
2154  $logins[] = $row['login'];
2155  }
2156 
2157  return $logins;
2158  }
2159 
2164  public static function _readUsersProfileData(array $a_user_ids): array
2165  {
2166  global $DIC;
2167 
2168  $ilDB = $DIC['ilDB'];
2169  $res = $ilDB->query('SELECT * FROM usr_data WHERE ' .
2170  $ilDB->in('usr_id', $a_user_ids, false, 'integer'));
2171  $user_data = [];
2172  while ($row = $ilDB->fetchAssoc($res)) {
2173  $user_data[$row['usr_id']] = $row;
2174  }
2175  return $user_data;
2176  }
2177 
2183  public static function _getAllUserData(
2184  ?array $a_fields = null,
2185  int $active = -1
2186  ): array {
2187  global $DIC;
2188 
2189  $ilDB = $DIC['ilDB'];
2190 
2191  $result_arr = [];
2192 
2193  if ($a_fields !== null and is_array($a_fields)) {
2194  if (count($a_fields) == 0) {
2195  $select = '*';
2196  } else {
2197  if (($usr_id_field = array_search('usr_id', $a_fields)) !== false) {
2198  unset($a_fields[$usr_id_field]);
2199  }
2200 
2201  $select = implode(',', $a_fields) . ',usr_data.usr_id';
2202  // online time
2203  if (in_array('online_time', $a_fields)) {
2204  $select .= ',ut_online.online_time ';
2205  }
2206  }
2207 
2208  $q = 'SELECT ' . $select . ' FROM usr_data ';
2209 
2210  // Add online_time if desired
2211  // Need left join here to show users that never logged in
2212  if (in_array('online_time', $a_fields)) {
2213  $q .= 'LEFT JOIN ut_online ON usr_data.usr_id = ut_online.usr_id ';
2214  }
2215 
2216  switch ($active) {
2217  case 0:
2218  case 1:
2219  $q .= 'WHERE active = ' . $ilDB->quote($active, 'integer');
2220  break;
2221  case 2:
2222  $q .= 'WHERE time_limit_unlimited= ' . $ilDB->quote(0, 'integer');
2223  break;
2224  case 3:
2225  $qtemp = $q . ', rbac_ua, object_data WHERE rbac_ua.rol_id = object_data.obj_id AND ' .
2226  $ilDB->like('object_data.title', 'text', '%crs%') . ' AND usr_data.usr_id = rbac_ua.usr_id';
2227  $r = $ilDB->query($qtemp);
2228  $course_users = [];
2229  while ($row = $ilDB->fetchAssoc($r)) {
2230  $course_users[] = $row['usr_id'];
2231  }
2232  if (count($course_users)) {
2233  $q .= ' WHERE ' . $ilDB->in('usr_data.usr_id', $course_users, true, 'integer') . ' ';
2234  } else {
2235  return $result_arr;
2236  }
2237  break;
2238  case 4:
2239  $session_data = ilSession::get('user_filter_data');
2240  $date = date('Y-m-d H:i:s', mktime(0, 0, 0, $session_data['m'], $session_data['d'], $session_data['y']));
2241  $q .= ' AND last_login < ' . $ilDB->quote($date, 'timestamp');
2242  break;
2243  case 5:
2244  $ref_id = ilSession::get('user_filter_data');
2245  if ($ref_id) {
2246  $q .= ' LEFT JOIN obj_members ON usr_data.usr_id = obj_members.usr_id ' .
2247  'WHERE obj_members.obj_id = (SELECT obj_id FROM object_reference ' .
2248  'WHERE ref_id = ' . $ilDB->quote($ref_id, 'integer') . ') ';
2249  }
2250  break;
2251  case 6:
2252  global $DIC;
2253 
2254  $rbacreview = $DIC['rbacreview'];
2255  $ref_id = ilSession::get('user_filter_data');
2256  if ($ref_id) {
2257  $local_roles = $rbacreview->getRolesOfRoleFolder($ref_id, false);
2258  if (is_array($local_roles) && count($local_roles)) {
2259  $q .= ' LEFT JOIN rbac_ua ON usr_data.usr_id = rbac_ua.usr_id WHERE ' .
2260  $ilDB->in('rbac_ua.rol_id', $local_roles, false, 'integer') . ' ';
2261  }
2262  }
2263  break;
2264  case 7:
2265  $rol_id = ilSession::get('user_filter_data');
2266  if ($rol_id) {
2267  $q .= ' LEFT JOIN rbac_ua ON usr_data.usr_id = rbac_ua.usr_id WHERE rbac_ua.rol_id = ' .
2268  $ilDB->quote($rol_id, 'integer');
2269  }
2270  break;
2271  }
2272  $r = $ilDB->query($q);
2273 
2274  while ($row = $ilDB->fetchAssoc($r)) {
2275  $result_arr[] = $row;
2276  }
2277  }
2278 
2279  return $result_arr;
2280  }
2281 
2282  public static function _getNumberOfUsersForStyle(
2283  string $a_skin,
2284  string $a_style
2285  ): int {
2286  global $DIC;
2287 
2288  $ilDB = $DIC['ilDB'];
2289 
2290  $q = 'SELECT count(*) as cnt FROM usr_pref up1, usr_pref up2 ' .
2291  ' WHERE up1.keyword= ' . $ilDB->quote('style', 'text') .
2292  ' AND up1.value= ' . $ilDB->quote($a_style, 'text') .
2293  ' AND up2.keyword= ' . $ilDB->quote('skin', 'text') .
2294  ' AND up2.value= ' . $ilDB->quote($a_skin, 'text') .
2295  ' AND up1.usr_id = up2.usr_id ';
2296 
2297  $cnt_set = $ilDB->query($q);
2298 
2299  $cnt_rec = $ilDB->fetchAssoc($cnt_set);
2300 
2301  return (int) $cnt_rec['cnt'];
2302  }
2303 
2307  public static function _getAllUserAssignedStyles(): array
2308  {
2309  global $DIC;
2310 
2311  $ilDB = $DIC['ilDB'];
2312 
2313  $q = 'SELECT DISTINCT up1.value style, up2.value skin FROM usr_pref up1, usr_pref up2 ' .
2314  ' WHERE up1.keyword = ' . $ilDB->quote('style', 'text') .
2315  ' AND up2.keyword = ' . $ilDB->quote('skin', 'text') .
2316  ' AND up1.usr_id = up2.usr_id';
2317 
2318  $sty_set = $ilDB->query($q);
2319 
2320  $styles = [];
2321  while ($sty_rec = $ilDB->fetchAssoc($sty_set)) {
2322  $styles[] = $sty_rec['skin'] . ':' . $sty_rec['style'];
2323  }
2324 
2325  return $styles;
2326  }
2327 
2328  public static function _moveUsersToStyle(
2329  string $a_from_skin,
2330  string $a_from_style,
2331  string $a_to_skin,
2332  string $a_to_style
2333  ): void {
2334  global $DIC;
2335 
2336  $ilDB = $DIC['ilDB'];
2337 
2338  $q = 'SELECT up1.usr_id usr_id FROM usr_pref up1, usr_pref up2 ' .
2339  ' WHERE up1.keyword= ' . $ilDB->quote('style', 'text') .
2340  ' AND up1.value= ' . $ilDB->quote($a_from_style, 'text') .
2341  ' AND up2.keyword= ' . $ilDB->quote('skin', 'text') .
2342  ' AND up2.value= ' . $ilDB->quote($a_from_skin, 'text') .
2343  ' AND up1.usr_id = up2.usr_id ';
2344 
2345  $usr_set = $ilDB->query($q);
2346 
2347  while ($usr_rec = $ilDB->fetchAssoc($usr_set)) {
2348  self::_writePref($usr_rec['usr_id'], 'skin', $a_to_skin);
2349  self::_writePref($usr_rec['usr_id'], 'style', $a_to_style);
2350  }
2351  }
2352 
2353 
2359 
2366  public function addObjectToClipboard(
2367  int $a_item_id,
2368  string $a_type,
2369  string $a_title,
2370  int $a_parent = 0,
2371  string $a_time = '',
2372  int $a_order_nr = 0
2373  ): void {
2374  global $DIC;
2375 
2376  $ilDB = $DIC['ilDB'];
2377 
2378  if ($a_time === '') {
2379  $a_time = date('Y-m-d H:i:s');
2380  }
2381 
2382  $item_set = $ilDB->queryF(
2383  'SELECT * FROM personal_clipboard WHERE ' .
2384  'parent = %s AND item_id = %s AND type = %s AND user_id = %s',
2385  ['integer', 'integer', 'text', 'integer'],
2386  [0, $a_item_id, $a_type, $this->getId()]
2387  );
2388 
2389  // only insert if item is not already in clipboard
2390  if (!$item_set->fetchRow()) {
2391  $ilDB->manipulateF(
2392  'INSERT INTO personal_clipboard ' .
2393  '(item_id, type, user_id, title, parent, insert_time, order_nr) VALUES ' .
2394  ' (%s,%s,%s,%s,%s,%s,%s)',
2395  ['integer', 'text', 'integer', 'text', 'integer', 'timestamp', 'integer'],
2396  [$a_item_id, $a_type, $this->getId(), $a_title, $a_parent, $a_time, $a_order_nr]
2397  );
2398  } else {
2399  $ilDB->manipulateF(
2400  'UPDATE personal_clipboard SET insert_time = %s ' .
2401  'WHERE user_id = %s AND item_id = %s AND type = %s AND parent = 0',
2402  ['timestamp', 'integer', 'integer', 'text'],
2403  [$a_time, $this->getId(), $a_item_id, $a_type]
2404  );
2405  }
2406  }
2407 
2412  public function addToPCClipboard(
2413  string $a_content,
2414  string $a_time,
2415  int $a_nr
2416  ): void {
2417  $ilDB = $this->db;
2418  if ($a_time == 0) {
2419  $a_time = date('Y-m-d H:i:s');
2420  }
2421  ilSession::set('user_pc_clip', true);
2422  $ilDB->insert('personal_pc_clipboard', [
2423  'user_id' => ['integer', $this->getId()],
2424  'content' => ['clob', $a_content],
2425  'insert_time' => ['timestamp', $a_time],
2426  'order_nr' => ['integer', $a_nr]
2427  ]);
2428  }
2429 
2434  public function getPCClipboardContent(): array // Missing array type.
2435  {
2436  $ilDB = $this->db;
2437 
2438  if (!ilSession::get('user_pc_clip')) {
2439  return [];
2440  }
2441 
2442  $set = $ilDB->queryF('SELECT MAX(insert_time) mtime FROM personal_pc_clipboard ' .
2443  ' WHERE user_id = %s', ['integer'], [$this->getId()]);
2444  $row = $ilDB->fetchAssoc($set);
2445 
2446  $set = $ilDB->queryF(
2447  'SELECT * FROM personal_pc_clipboard ' .
2448  ' WHERE user_id = %s AND insert_time = %s ORDER BY order_nr ASC',
2449  ['integer', 'timestamp'],
2450  [$this->getId(), $row['mtime']]
2451  );
2452  $content = [];
2453  while ($row = $ilDB->fetchAssoc($set)) {
2454  $content[] = $row['content'];
2455  }
2456 
2457  return $content;
2458  }
2459 
2463  public function clipboardHasObjectsOfType(string $a_type): bool
2464  {
2465  global $DIC;
2466 
2467  $ilDB = $DIC['ilDB'];
2468 
2469  $set = $ilDB->queryF(
2470  'SELECT * FROM personal_clipboard WHERE ' .
2471  'parent = %s AND type = %s AND user_id = %s',
2472  ['integer', 'text', 'integer'],
2473  [0, $a_type, $this->getId()]
2474  );
2475  if ($ilDB->fetchAssoc($set)) {
2476  return true;
2477  }
2478 
2479  return false;
2480  }
2481 
2482  public function clipboardDeleteObjectsOfType(string $a_type): void
2483  {
2484  $ilDB = $this->db;
2485 
2486  $ilDB->manipulateF(
2487  'DELETE FROM personal_clipboard WHERE ' .
2488  'type = %s AND user_id = %s',
2489  ['text', 'integer'],
2490  [$a_type, $this->getId()]
2491  );
2492  }
2493 
2494  public function clipboardDeleteAll(): void
2495  {
2496  global $DIC;
2497 
2498  $ilDB = $DIC['ilDB'];
2499 
2500  $ilDB->manipulateF('DELETE FROM personal_clipboard WHERE ' .
2501  'user_id = %s', ['integer'], [$this->getId()]);
2502  }
2503 
2507  public function getClipboardObjects(
2508  string $a_type = '',
2509  bool $a_top_nodes_only = false
2510  ): array {
2511  global $DIC;
2512 
2513  $ilDB = $DIC['ilDB'];
2514 
2515  $par = '';
2516  if ($a_top_nodes_only) {
2517  $par = ' AND parent = ' . $ilDB->quote(0, 'integer') . ' ';
2518  }
2519 
2520  $type_str = ($a_type != '')
2521  ? ' AND type = ' . $ilDB->quote($a_type, 'text') . ' '
2522  : '';
2523  $q = 'SELECT * FROM personal_clipboard WHERE ' .
2524  'user_id = ' . $ilDB->quote($this->getId(), 'integer') . ' ' .
2525  $type_str . $par .
2526  ' ORDER BY order_nr';
2527  $objs = $ilDB->query($q);
2528  $objects = [];
2529  while ($obj = $ilDB->fetchAssoc($objs)) {
2530  if ($obj['type'] == 'mob') {
2531  $obj['title'] = ilObject::_lookupTitle($obj['item_id']);
2532  if (ilObject::_lookupType((int) $obj['item_id']) !== 'mob') {
2533  continue;
2534  }
2535  }
2536  if ($obj['type'] == 'incl') {
2537  $obj['title'] = ilMediaPoolPage::lookupTitle($obj['item_id']);
2538  if (!ilPageObject::_exists('mep', (int) $obj['item_id'], '-')) {
2539  continue;
2540  }
2541  }
2542  $objects[] = ['id' => $obj['item_id'],
2543  'type' => $obj['type'], 'title' => $obj['title'],
2544  'insert_time' => $obj['insert_time']];
2545  }
2546  return $objects;
2547  }
2548 
2552  public function getClipboardChilds(
2553  int $a_parent,
2554  string $a_insert_time
2555  ): array {
2556  global $DIC;
2557 
2558  $ilDB = $DIC['ilDB'];
2559  $ilUser = $DIC['ilUser'];
2560 
2561  $objs = $ilDB->queryF(
2562  'SELECT * FROM personal_clipboard WHERE ' .
2563  'user_id = %s AND parent = %s AND insert_time = %s ' .
2564  ' ORDER BY order_nr',
2565  ['integer', 'integer', 'timestamp'],
2566  [$ilUser->getId(), $a_parent, $a_insert_time]
2567  );
2568  $objects = [];
2569  while ($obj = $ilDB->fetchAssoc($objs)) {
2570  if ($obj['type'] == 'mob') {
2571  $obj['title'] = ilObject::_lookupTitle($obj['item_id']);
2572  }
2573  $objects[] = ['id' => $obj['item_id'],
2574  'type' => $obj['type'], 'title' => $obj['title'], 'insert_time' => $obj['insert_time']];
2575  }
2576  return $objects;
2577  }
2578 
2583  public static function _getUsersForClipboadObject(
2584  string $a_type,
2585  int $a_id
2586  ): array {
2587  global $DIC;
2588 
2589  $ilDB = $DIC['ilDB'];
2590 
2591  $q = 'SELECT DISTINCT user_id FROM personal_clipboard WHERE ' .
2592  'item_id = ' . $ilDB->quote($a_id, 'integer') . ' AND ' .
2593  'type = ' . $ilDB->quote($a_type, 'text');
2594  $user_set = $ilDB->query($q);
2595  $users = [];
2596  while ($user_rec = $ilDB->fetchAssoc($user_set)) {
2597  $users[] = (int) $user_rec['user_id'];
2598  }
2599 
2600  return $users;
2601  }
2602 
2603  public function removeObjectFromClipboard(
2604  int $a_item_id,
2605  string $a_type
2606  ): void {
2607  $ilDB = $this->db;
2608 
2609  $q = 'DELETE FROM personal_clipboard WHERE ' .
2610  'item_id = ' . $ilDB->quote($a_item_id, 'integer') .
2611  ' AND type = ' . $ilDB->quote($a_type, 'text') . ' ' .
2612  ' AND user_id = ' . $ilDB->quote($this->getId(), 'integer');
2613  $ilDB->manipulate($q);
2614  }
2615 
2616  public static function _getImportedUserId(
2617  string $i2_id
2618  ): int {
2619  global $DIC;
2620 
2621  $ilDB = $DIC['ilDB'];
2622 
2623  $query = 'SELECT obj_id FROM object_data WHERE import_id = ' .
2624  $ilDB->quote($i2_id, 'text');
2625 
2626  $res = $ilDB->query($query);
2627  $id = 0;
2628  while ($row = $ilDB->fetchObject($res)) {
2629  $id = (int) $row->obj_id;
2630  }
2631  return $id;
2632  }
2633 
2637  public static function lookupOrgUnitsRepresentation(
2638  int $a_usr_id
2639  ): string {
2640  return ilOrgUnitPathStorage::getTextRepresentationOfUsersOrgUnits($a_usr_id);
2641  }
2642 
2643  public function getOrgUnitsRepresentation(): string
2644  {
2645  return self::lookupOrgUnitsRepresentation($this->getId());
2646  }
2647 
2648  public function setAuthMode(?string $a_str): void
2649  {
2650  $this->auth_mode = $a_str;
2651  }
2652 
2653  public function getAuthMode(bool $a_auth_key = false): ?string
2654  {
2655  if (!$a_auth_key) {
2656  return $this->auth_mode;
2657  }
2658  return ilAuthUtils::_getAuthMode($this->auth_mode);
2659  }
2660 
2661  public function setExternalAccount(string $a_str): void
2662  {
2663  $this->ext_account = $a_str;
2664  }
2665 
2666  public function getExternalAccount(): string
2667  {
2668  return $this->ext_account;
2669  }
2670 
2677  public static function _getExternalAccountsByAuthMode(
2678  string $a_auth_mode,
2679  bool $a_read_auth_default = false
2680  ): array {
2681  global $DIC;
2682 
2683  $ilDB = $DIC['ilDB'];
2684  $ilSetting = $DIC['ilSetting'];
2685 
2686  $q = 'SELECT login,usr_id,ext_account,auth_mode FROM usr_data ' .
2687  'WHERE auth_mode = %s';
2688  $types[] = 'text';
2689  $values[] = $a_auth_mode;
2690  if ($a_read_auth_default and ilAuthUtils::_getAuthModeName($ilSetting->get('auth_mode', ilAuthUtils::AUTH_LOCAL)) == $a_auth_mode) {
2691  $q .= ' OR auth_mode = %s ';
2692  $types[] = 'text';
2693  $values[] = 'default';
2694  }
2695 
2696  $res = $ilDB->queryF($q, $types, $values);
2697  $accounts = [];
2698  while ($row = $ilDB->fetchObject($res)) {
2699  if ($row->auth_mode == 'default') {
2700  $accounts[$row->usr_id] = $row->login;
2701  } else {
2702  $accounts[$row->usr_id] = $row->ext_account;
2703  }
2704  }
2705  return $accounts;
2706  }
2707 
2708  public static function _toggleActiveStatusOfUsers(
2709  array $a_usr_ids,
2710  bool $a_status
2711  ): void {
2712  global $DIC;
2713 
2714  $ilDB = $DIC['ilDB'];
2715 
2716  if ($a_status) {
2717  $q = 'UPDATE usr_data SET active = 1, inactivation_date = NULL WHERE ' .
2718  $ilDB->in('usr_id', $a_usr_ids, false, 'integer');
2719  $ilDB->manipulate($q);
2720  } else {
2721  $usrId_IN_usrIds = $ilDB->in('usr_id', $a_usr_ids, false, 'integer');
2722 
2723  $q = 'UPDATE usr_data SET active = 0 WHERE $usrId_IN_usrIds';
2724  $ilDB->manipulate($q);
2725 
2726  $queryString = '
2727  UPDATE usr_data
2728  SET inactivation_date = %s
2729  WHERE inactivation_date IS NULL
2730  AND $usrId_IN_usrIds
2731  ';
2732  $ilDB->manipulateF($queryString, ['timestamp'], [ilUtil::now()]);
2733  }
2734  }
2735 
2736  public static function _lookupAuthMode(int $a_usr_id): string
2737  {
2738  return (string) self::_lookup($a_usr_id, 'auth_mode');
2739  }
2740 
2745  public static function _checkExternalAuthAccount(
2746  string $a_auth,
2747  string $a_account,
2748  bool $tryFallback = true
2749  ): ?string {
2750  $db = $GLOBALS['DIC']->database();
2751  $settings = $GLOBALS['DIC']->settings();
2752 
2753  // Check directly with auth_mode
2754  $r = $db->queryF(
2755  'SELECT * FROM usr_data WHERE ' .
2756  ' ext_account = %s AND auth_mode = %s',
2757  ['text', 'text'],
2758  [$a_account, $a_auth]
2759  );
2760  if ($usr = $db->fetchAssoc($r)) {
2761  return $usr['login'];
2762  }
2763 
2764  if (!$tryFallback) {
2765  return null;
2766  }
2767 
2768  // For compatibility, check for login (no ext_account entry given)
2769  $res = $db->queryF(
2770  'SELECT login FROM usr_data ' .
2771  'WHERE login = %s AND auth_mode = %s AND (ext_account IS NULL OR ext_account = "") ',
2772  ['text', 'text'],
2773  [$a_account, $a_auth]
2774  );
2775  if ($usr = $db->fetchAssoc($res)) {
2776  return $usr['login'];
2777  }
2778 
2779  // If auth_default == $a_auth => check for login
2780  if (ilAuthUtils::_getAuthModeName($settings->get('auth_mode')) == $a_auth) {
2781  $res = $db->queryF(
2782  'SELECT login FROM usr_data WHERE ' .
2783  ' ext_account = %s AND auth_mode = %s',
2784  ['text', 'text'],
2785  [$a_account, 'default']
2786  );
2787  if ($usr = $db->fetchAssoc($res)) {
2788  return $usr['login'];
2789  }
2790  // Search for login (no ext_account given)
2791  $res = $db->queryF(
2792  'SELECT login FROM usr_data ' .
2793  'WHERE login = %s AND (ext_account IS NULL OR ext_account = "") AND auth_mode = %s',
2794  ['text', 'text'],
2795  [$a_account, 'default']
2796  );
2797  if ($usr = $db->fetchAssoc($res)) {
2798  return $usr['login'];
2799  }
2800  }
2801  return null;
2802  }
2803 
2807  public static function _getNumberOfUsersPerAuthMode(): array // Missing array type.
2808  {
2809  global $DIC;
2810 
2811  $ilDB = $DIC['ilDB'];
2812 
2813  $r = $ilDB->query('SELECT count(*) AS cnt, auth_mode FROM usr_data ' .
2814  'GROUP BY auth_mode');
2815  $cnt_arr = [];
2816  while ($cnt = $ilDB->fetchAssoc($r)) {
2817  $cnt_arr[$cnt['auth_mode']] = (int) $cnt['cnt'];
2818  }
2819 
2820  return $cnt_arr;
2821  }
2822 
2823  public static function _getLocalAccountsForEmail(string $a_email): array // Missing array type.
2824  {
2825  global $DIC;
2826 
2827  $ilDB = $DIC['ilDB'];
2828  $ilSetting = $DIC['ilSetting'];
2829 
2830  // default set to local (1)?
2831 
2832  $q = 'SELECT * FROM usr_data WHERE ' .
2833  ' email = %s AND (auth_mode = %s ';
2834  $types = ['text', 'text'];
2835  $values = [$a_email, 'local'];
2836 
2837  if ($ilSetting->get('auth_mode') == 1) {
2838  $q .= ' OR auth_mode = %s';
2839  $types[] = 'text';
2840  $values[] = 'default';
2841  }
2842 
2843  $q .= ')';
2844 
2845  $users = [];
2846  $usr_set = $ilDB->queryF($q, $types, $values);
2847  while ($usr_rec = $ilDB->fetchAssoc($usr_set)) {
2848  $users[$usr_rec['usr_id']] = $usr_rec['login'];
2849  }
2850 
2851  return $users;
2852  }
2853 
2854 
2859  public static function _uploadPersonalPicture(
2860  string $tmp_file,
2861  int $obj_id
2862  ): bool {
2863  global $DIC;
2864  $user = new ilObjUser($obj_id);
2865  $stakeholder = new ilUserProfilePictureStakeholder();
2866  $stakeholder->setOwner($user->getId());
2867  $stream = Streams::ofResource(fopen($tmp_file, 'rb'));
2868 
2870  $rid = $DIC->resourceStorage()->manage()->find($user->getAvatarRid());
2871  // append profile picture
2872  $DIC->resourceStorage()->manage()->replaceWithStream(
2873  $rid,
2874  $stream,
2875  $stakeholder
2876  );
2877  } else {
2878  // new profile picture
2879  $rid = $DIC->resourceStorage()->manage()->stream(
2880  $stream,
2881  $stakeholder
2882  );
2883  }
2884 
2885  $user->setAvatarRid($rid->serialize());
2886  $user->update();
2887  return true;
2888  }
2889 
2890 
2895  public function getPersonalPicturePath(
2896  string $a_size = 'small',
2897  bool $a_force_pic = false
2898  ): string {
2899  if (isset(self::$personal_image_cache[$this->getId()][$a_size][(int) $a_force_pic])) {
2900  return self::$personal_image_cache[$this->getId()][$a_size][(int) $a_force_pic];
2901  }
2902 
2903  self::$personal_image_cache[$this->getId()][$a_size][(int) $a_force_pic] = self::_getPersonalPicturePath($this->getId(), $a_size, $a_force_pic);
2904 
2905  return self::$personal_image_cache[$this->getId()][$a_size][(int) $a_force_pic];
2906  }
2907 
2908  public function hasProfilePicture(): bool
2909  {
2910  return (new ilUserAvatarResolver($this->getId()))->hasProfilePicture();
2911  }
2912 
2913  public function getAvatar(): Avatar
2914  {
2915  return self::_getAvatar($this->getId());
2916  }
2917 
2918  public static function _getAvatar(int $a_usr_id): Avatar
2919  {
2920  $define = new ilUserAvatarResolver($a_usr_id ?: ANONYMOUS_USER_ID);
2921  $define->setSize('xsmall');
2922  return $define->getAvatar();
2923  }
2924 
2929  public static function _getPersonalPicturePath(
2930  int $a_usr_id,
2931  string $a_size = 'small',
2932  bool $a_force_pic = false,
2933  bool $a_prevent_no_photo_image = false,
2934  bool $html_export = false
2935  ): string {
2936  $define = new ilUserAvatarResolver($a_usr_id);
2937  $define->setForcePicture($a_force_pic);
2938  $define->setSize($a_size);
2939  return $define->getLegacyPictureURL();
2940  }
2941 
2942  public static function copyProfilePicturesToDirectory(
2943  int $a_user_id,
2944  string $a_dir
2945  ): void {
2946  $a_dir = trim(str_replace('..', '', $a_dir));
2947  if ($a_dir == '' || !is_dir($a_dir)) {
2948  return;
2949  }
2950  // if profile picture is on IRSS
2951  global $DIC;
2952  $irss = $DIC->resourceStorage();
2953  $user = new ilObjUser($a_user_id);
2955  $rid = $irss->manage()->find($user->getAvatarRid());
2956  // Main Picture only is needed
2957  $stream = $irss->consume()->stream($rid)->getStream();
2958  $target = $a_dir . '/usr_' . $a_user_id . '.jpg';
2959  fwrite(fopen($target, 'wb'), (string) $stream);
2960 
2961  return;
2962  }
2963 
2964  // Legacy Picture Handling
2965  $webspace_dir = ilFileUtils::getWebspaceDir();
2966  $image_dir = $webspace_dir . '/usr_images';
2967  $images = [
2968  'upload_' . $a_user_id . 'pic',
2969  'usr_' . $a_user_id . '.' . 'jpg',
2970  'usr_' . $a_user_id . '_small.jpg',
2971  'usr_' . $a_user_id . '_xsmall.jpg',
2972  'usr_' . $a_user_id . '_xxsmall.jpg',
2973  'upload_' . $a_user_id];
2974  foreach ($images as $image) {
2975  if (is_file($image_dir . '/' . $image)) {
2976  copy($image_dir . '/' . $image, $a_dir . '/' . $image);
2977  }
2978  }
2979  }
2980 
2981 
2982  public function removeUserPicture(
2983  bool $a_do_update = true
2984  ): void {
2985  if ($this->getAvatarRid() !== null && $this->getAvatarRid() !== self::NO_AVATAR_RID) {
2986  $rid = $this->irss->manage()->find($this->getAvatarRid());
2987  $this->irss->manage()->remove($rid, new ilUserProfilePictureStakeholder());
2988  }
2989 
2990  if ($a_do_update) {
2991  // remove user pref file name
2993  $this->setPref('profile_image', '');
2994  $this->update();
2995  }
2996  }
2997 
2998 
2999  public function setUserDefinedData(array $a_data): void // Missing array type.
3000  {
3001  foreach ($a_data as $field => $data) {
3002  $this->user_defined_data['f_' . $field] = $data;
3003  }
3004  }
3005 
3006  public function getUserDefinedData(): array // Missing array type.
3007  {
3008  return $this->user_defined_data ?: [];
3009  }
3010 
3011  public function updateUserDefinedFields(): void
3012  {
3013  $udata = new ilUserDefinedData($this->getId());
3014  foreach ($this->user_defined_data as $field => $value) {
3015  if ($field !== 'usr_id' && $value !== null) {
3016  $udata->set($field, $value);
3017  }
3018  }
3019  $udata->update();
3020  }
3021 
3022  public function readUserDefinedFields(): void
3023  {
3024  $udata = new ilUserDefinedData($this->getId());
3025  $this->user_defined_data = $udata->getAll();
3026  }
3027 
3028  public function deleteUserDefinedFieldEntries(): void
3029  {
3031  }
3032 
3037  public function getProfileAsString(Language $language): string
3038  {
3039  global $DIC;
3040 
3041  $rbacreview = $DIC['rbacreview'];
3042 
3043  $language->loadLanguageModule('registration');
3044  $language->loadLanguageModule('crs');
3045 
3046  $body = ($language->txt('login') . ': ' . $this->getLogin() . "\n");
3047 
3048  if (strlen($this->getUTitle())) {
3049  $body .= ($language->txt('title') . ': ' . $this->getUTitle() . "\n");
3050  }
3051  if (1 === strlen($this->getGender())) {
3052  $body .= ($language->txt('gender') . ': ' . $language->txt('gender_' . strtolower($this->getGender())) . "\n");
3053  }
3054  if (strlen($this->getFirstname())) {
3055  $body .= ($language->txt('firstname') . ': ' . $this->getFirstname() . "\n");
3056  }
3057  if (strlen($this->getLastname())) {
3058  $body .= ($language->txt('lastname') . ': ' . $this->getLastname() . "\n");
3059  }
3060  if (strlen($this->getInstitution())) {
3061  $body .= ($language->txt('institution') . ': ' . $this->getInstitution() . "\n");
3062  }
3063  if (strlen($this->getDepartment())) {
3064  $body .= ($language->txt('department') . ': ' . $this->getDepartment() . "\n");
3065  }
3066  if (strlen($this->getStreet())) {
3067  $body .= ($language->txt('street') . ': ' . $this->getStreet() . "\n");
3068  }
3069  if (strlen($this->getCity())) {
3070  $body .= ($language->txt('city') . ': ' . $this->getCity() . "\n");
3071  }
3072  if (strlen($this->getZipcode())) {
3073  $body .= ($language->txt('zipcode') . ': ' . $this->getZipcode() . "\n");
3074  }
3075  if (strlen($this->getCountry())) {
3076  $body .= ($language->txt('country') . ': ' . $this->getCountry() . "\n");
3077  }
3078  if (strlen($this->getSelectedCountry())) {
3079  $body .= ($language->txt('sel_country') . ': ' . $this->getSelectedCountry() . "\n");
3080  }
3081  if (strlen($this->getPhoneOffice())) {
3082  $body .= ($language->txt('phone_office') . ': ' . $this->getPhoneOffice() . "\n");
3083  }
3084  if (strlen($this->getPhoneHome())) {
3085  $body .= ($language->txt('phone_home') . ': ' . $this->getPhoneHome() . "\n");
3086  }
3087  if (strlen($this->getPhoneMobile())) {
3088  $body .= ($language->txt('phone_mobile') . ': ' . $this->getPhoneMobile() . "\n");
3089  }
3090  if (strlen($this->getFax())) {
3091  $body .= ($language->txt('fax') . ': ' . $this->getFax() . "\n");
3092  }
3093  if ($this->getEmail() !== '') {
3094  $body .= ($language->txt('email') . ': ' . $this->getEmail() . "\n");
3095  }
3096  if ($this->getSecondEmail() !== null
3097  && $this->getSecondEmail() !== '') {
3098  $body .= ($language->txt('second_email') . ': ' . $this->getSecondEmail() . "\n");
3099  }
3100  if (strlen($this->getHobby())) {
3101  $body .= ($language->txt('hobby') . ': ' . $this->getHobby() . "\n");
3102  }
3103  if (strlen($this->getComment())) {
3104  $body .= ($language->txt('referral_comment') . ': ' . $this->getComment() . "\n");
3105  }
3106  if (strlen($this->getMatriculation())) {
3107  $body .= ($language->txt('matriculation') . ': ' . $this->getMatriculation() . "\n");
3108  }
3109  if (strlen($this->getCreateDate())) {
3114 
3115  $body .= ($language->txt('create_date') . ': ' . $date . "\n");
3116  }
3117 
3118  $gr = [];
3119  foreach ($rbacreview->getGlobalRoles() as $role) {
3120  if ($rbacreview->isAssigned($this->getId(), $role)) {
3121  $gr[] = ilObjRole::_lookupTitle($role);
3122  }
3123  }
3124  if (count($gr)) {
3125  $body .= ($language->txt('reg_role_info') . ': ' . implode(',', $gr) . "\n");
3126  }
3127 
3128  // Time limit
3129  if ($this->getTimeLimitUnlimited()) {
3130  $body .= ($language->txt('time_limit') . ': ' . $language->txt('crs_unlimited') . "\n");
3131  } else {
3135  new ilDateTime($this->getTimeLimitFrom(), IL_CAL_UNIX),
3137  );
3139 
3140  $start = new ilDateTime($this->getTimeLimitFrom(), IL_CAL_UNIX);
3141  $end = new ilDateTime($this->getTimeLimitUntil(), IL_CAL_UNIX);
3142 
3143  $body .= $language->txt('time_limit') . ': ' .
3144  $language->txt('from') . ' ' .
3145  $start->get(IL_CAL_DATETIME) . ' ';
3146  $body .= $language->txt('to') . ' ' . $end->get(IL_CAL_DATETIME) . "\n";
3147  }
3148 
3152  $user_defined_fields = ilUserDefinedFields::_getInstance();
3153  $user_defined_data = $this->getUserDefinedData();
3154 
3155  foreach ($user_defined_fields->getDefinitions() as $field_id => $definition) {
3156  $data = $user_defined_data['f_' . $field_id] ?? '';
3157  if ($data !== '') {
3158  if ($definition['field_type'] == UDF_TYPE_WYSIWYG) {
3159  $data = strip_tags(
3160  preg_replace('/<br(\s*)?\/?>/i', "\n", $data)
3161  );
3162  }
3163 
3164  $body .= $definition['field_name'] . ': ' . $data . "\n";
3165  }
3166  }
3167 
3168  return $body;
3169  }
3170 
3174  public static function _lookupFeedHash(
3175  int $user_id,
3176  bool $create = false
3177  ): ?string {
3178  global $DIC;
3179  $ilDB = $DIC['ilDB'];
3180 
3181  if ($user_id === 0) {
3182  return null;
3183  }
3184 
3185  $set = $ilDB->queryF(
3186  'SELECT feed_hash from usr_data WHERE usr_id = %s',
3188  [$user_id]
3189  );
3190  if (($rec = $ilDB->fetchAssoc($set)) === null) {
3191  return null;
3192  }
3193 
3194  $feed_hash = $rec['feed_hash'];
3195  if (is_string($feed_hash) && strlen($feed_hash) === 32) {
3196  return $feed_hash;
3197  }
3198 
3199  if (!$create) {
3200  return null;
3201  }
3202 
3203  $hash = md5(random_int(1, 9999999) + str_replace(' ', '', microtime()));
3204  $ilDB->manipulateF(
3205  'UPDATE usr_data SET feed_hash = %s' .
3206  ' WHERE usr_id = %s',
3208  [$hash, $user_id]
3209  );
3210  return $hash;
3211  }
3212 
3218  public static function _getFeedPass(
3219  int $a_user_id
3220  ): ?string {
3221  if ($a_user_id > 0) {
3222  return self::_lookupPref($a_user_id, 'priv_feed_pass');
3223  }
3224  return null;
3225  }
3226 
3231  public static function _setFeedPass(
3232  int $a_user_id,
3233  string $a_password
3234  ): void {
3235  self::_writePref(
3236  $a_user_id,
3237  'priv_feed_pass',
3238  ($a_password == '') ? '' : md5($a_password)
3239  );
3240  }
3241 
3246  public static function _loginExists(
3247  string $a_login,
3248  int $a_user_id = 0
3249  ): ?int {
3250  global $DIC;
3251 
3252  $ilDB = $DIC['ilDB'];
3253 
3254  $q = 'SELECT DISTINCT login, usr_id FROM usr_data ' .
3255  'WHERE login = %s';
3256  $types[] = 'text';
3257  $values[] = $a_login;
3258 
3259  if ($a_user_id != 0) {
3260  $q .= ' AND usr_id != %s ';
3261  $types[] = 'integer';
3262  $values[] = $a_user_id;
3263  }
3264 
3265  $r = $ilDB->queryF($q, $types, $values);
3266 
3267  if ($row = $ilDB->fetchAssoc($r)) {
3268  return (int) $row['usr_id'];
3269  }
3270  return null;
3271  }
3272 
3276  public static function _externalAccountExists(
3277  string $a_external_account,
3278  string $a_auth_mode
3279  ): bool {
3280  global $DIC;
3281 
3282  $ilDB = $DIC['ilDB'];
3283 
3284  $res = $ilDB->queryF(
3285  'SELECT * FROM usr_data ' .
3286  'WHERE ext_account = %s AND auth_mode = %s',
3287  ['text', 'text'],
3288  [$a_external_account, $a_auth_mode]
3289  );
3290  return (bool) $ilDB->fetchAssoc($res);
3291  }
3292 
3297  public static function _getUsersForRole(
3298  int $role_id,
3299  int $active = -1
3300  ): array {
3301  global $DIC;
3302 
3303  $ilDB = $DIC['ilDB'];
3304  $rbacreview = $DIC['rbacreview'];
3305  $ids = $rbacreview->assignedUsers($role_id);
3306 
3307  if (count($ids) == 0) {
3308  $ids = [-1];
3309  }
3310 
3311  $query = 'SELECT usr_data.*, usr_pref.value AS language
3312  FROM usr_data
3313  LEFT JOIN usr_pref ON usr_pref.usr_id = usr_data.usr_id AND usr_pref.keyword = %s
3314  WHERE ' . $ilDB->in('usr_data.usr_id', $ids, false, 'integer');
3315  $values[] = 'language';
3316  $types[] = 'text';
3317 
3318 
3319  if (is_numeric($active) && $active > -1) {
3320  $query .= ' AND usr_data.active = %s';
3321  $values[] = $active;
3322  $types[] = 'integer';
3323  }
3324 
3325  $query .= ' ORDER BY usr_data.lastname, usr_data.firstname ';
3326 
3327  $r = $ilDB->queryF($query, $types, $values);
3328  $data = [];
3329  while ($row = $ilDB->fetchAssoc($r)) {
3330  $data[] = $row;
3331  }
3332  return $data;
3333  }
3334 
3335 
3340  public static function _getUsersForFolder(
3341  int $ref_id,
3342  int $active
3343  ): array {
3344  global $DIC;
3345 
3346  $ilDB = $DIC['ilDB'];
3347  $query = 'SELECT usr_data.*, usr_pref.value AS language FROM usr_data LEFT JOIN usr_pref ON usr_pref.usr_id = usr_data.usr_id and usr_pref.keyword = %s WHERE 1=1';
3348  $types[] = 'text';
3349  $values[] = 'language';
3350 
3351  if (is_numeric($active) && $active > -1) {
3352  $query .= ' AND usr_data.active = %s';
3353  $values[] = $active;
3354  $types[] = 'integer';
3355  }
3356 
3357  if ($ref_id != USER_FOLDER_ID) {
3358  $query .= ' AND usr_data.time_limit_owner = %s';
3359  $values[] = $ref_id;
3360  $types[] = 'integer';
3361  }
3362 
3363  $query .= ' AND usr_data.usr_id != %s ';
3364  $values[] = ANONYMOUS_USER_ID;
3365  $types[] = 'integer';
3366 
3367  $query .= ' ORDER BY usr_data.lastname, usr_data.firstname ';
3368 
3369  $result = $ilDB->queryF($query, $types, $values);
3370  $data = [];
3371  while ($row = $ilDB->fetchAssoc($result)) {
3372  $data[] = $row;
3373  }
3374 
3375  return $data;
3376  }
3377 
3378 
3384  public static function _getUsersForGroup(
3385  array $a_mem_ids,
3386  int $active = -1
3387  ): array {
3388  return self::_getUsersForIds($a_mem_ids, $active);
3389  }
3390 
3391 
3397  public static function _getUsersForIds(
3398  array $a_mem_ids,
3399  int $active = -1,
3400  int $timelimitowner = -1
3401  ): array {
3402  global $DIC;
3403 
3404  $ilDB = $DIC['ilDB'];
3405 
3406  $query = 'SELECT usr_data.*, usr_pref.value AS language
3407  FROM usr_data
3408  LEFT JOIN usr_pref ON usr_pref.usr_id = usr_data.usr_id AND usr_pref.keyword = %s
3409  WHERE ' . $ilDB->in('usr_data.usr_id', $a_mem_ids, false, 'integer') . '
3410  AND usr_data.usr_id != %s';
3411  $values[] = 'language';
3412  $types[] = 'text';
3413  $values[] = ANONYMOUS_USER_ID;
3414  $types[] = 'integer';
3415 
3416  if (is_numeric($active) && $active > -1) {
3417  $query .= ' AND active = %s';
3418  $values[] = $active;
3419  $types[] = 'integer';
3420  }
3421 
3422  if ($timelimitowner != USER_FOLDER_ID && $timelimitowner != -1) {
3423  $query .= ' AND usr_data.time_limit_owner = %s';
3424  $values[] = $timelimitowner;
3425  $types[] = 'integer';
3426  }
3427 
3428  $query .= ' ORDER BY usr_data.lastname, usr_data.firstname ';
3429 
3430  $result = $ilDB->queryF($query, $types, $values);
3431  $mem_arr = [];
3432  while ($row = $ilDB->fetchAssoc($result)) {
3433  $mem_arr[] = $row;
3434  }
3435 
3436  return $mem_arr;
3437  }
3438 
3439 
3440 
3445  public static function _getUserData(array $a_internalids): array
3446  {
3447  global $DIC;
3448 
3449  $ilDB = $DIC['ilDB'];
3450 
3451  $ids = [];
3452  if (is_array($a_internalids)) {
3453  foreach ($a_internalids as $internalid) {
3454  if (is_numeric($internalid)) {
3455  $ids[] = $internalid;
3456  } else {
3457  $parsedid = ilUtil::__extractId($internalid, IL_INST_ID);
3458  if (is_numeric($parsedid) && $parsedid > 0) {
3459  $ids[] = $parsedid;
3460  }
3461  }
3462  }
3463  }
3464  if (count($ids) == 0) {
3465  $ids [] = -1;
3466  }
3467 
3468  $query = 'SELECT usr_data.*, usr_pref.value AS language
3469  FROM usr_data
3470  LEFT JOIN usr_pref
3471  ON usr_pref.usr_id = usr_data.usr_id AND usr_pref.keyword = %s
3472  WHERE ' . $ilDB->in('usr_data.usr_id', $ids, false, 'integer');
3473  $values[] = 'language';
3474  $types[] = 'text';
3475 
3476  $query .= ' ORDER BY usr_data.lastname, usr_data.firstname ';
3477 
3478  $data = [];
3479  $result = $ilDB->queryF($query, $types, $values);
3480  while ($row = $ilDB->fetchAssoc($result)) {
3481  $data[] = $row;
3482  }
3483  return $data;
3484  }
3485 
3492  public static function _getPreferences(int $user_id): array
3493  {
3494  global $DIC;
3495 
3496  $ilDB = $DIC['ilDB'];
3497 
3498  $prefs = [];
3499 
3500  $r = $ilDB->queryF(
3501  'SELECT * FROM usr_pref WHERE usr_id = %s',
3502  ['integer'],
3503  [$user_id]
3504  );
3505 
3506  while ($row = $ilDB->fetchAssoc($r)) {
3507  $prefs[$row['keyword']] = $row['value'];
3508  }
3509 
3510  return $prefs;
3511  }
3512 
3517  public static function getUserSubsetByPreferenceValue(
3518  array $a_user_ids,
3519  string $a_keyword,
3520  string $a_val
3521  ): array {
3522  global $DIC;
3523 
3524  $ilDB = $DIC['ilDB'];
3525 
3526  $users = [];
3527  $set = $ilDB->query(
3528  'SELECT usr_id FROM usr_pref ' .
3529  ' WHERE keyword = ' . $ilDB->quote($a_keyword, 'text') .
3530  ' AND ' . $ilDB->in('usr_id', $a_user_ids, false, 'integer') .
3531  ' AND value = ' . $ilDB->quote($a_val, 'text')
3532  );
3533  while ($rec = $ilDB->fetchAssoc($set)) {
3534  $users[] = $rec['usr_id'];
3535  }
3536  return $users;
3537  }
3538 
3539  public static function _getLoginAttempts(
3540  int $a_usr_id
3541  ): int {
3542  global $DIC;
3543 
3544  $ilDB = $DIC['ilDB'];
3545 
3546  $query = 'SELECT login_attempts FROM usr_data WHERE usr_id = %s';
3547  $result = $ilDB->queryF($query, ['integer'], [$a_usr_id]);
3548  $record = $ilDB->fetchAssoc($result);
3549  return (int) ($record['login_attempts'] ?? 0);
3550  }
3551 
3552  public static function _incrementLoginAttempts(
3553  int $a_usr_id
3554  ): bool {
3555  global $DIC;
3556 
3557  $ilDB = $DIC['ilDB'];
3558 
3559  $query = 'UPDATE usr_data SET login_attempts = (login_attempts + 1) WHERE usr_id = %s';
3560  $affected = $ilDB->manipulateF($query, ['integer'], [$a_usr_id]);
3561 
3562  if ($affected) {
3563  return true;
3564  } else {
3565  return false;
3566  }
3567  }
3568 
3569  public static function _setUserInactive(
3570  int $a_usr_id
3571  ): bool {
3572  global $DIC;
3573 
3574  $ilDB = $DIC['ilDB'];
3575 
3576  $query = 'UPDATE usr_data SET active = 0, inactivation_date = %s WHERE usr_id = %s';
3577  $affected = $ilDB->manipulateF($query, ['timestamp', 'integer'], [ilUtil::now(), $a_usr_id]);
3578 
3579  if ($affected) {
3580  return true;
3581  } else {
3582  return false;
3583  }
3584  }
3585 
3589  public function hasPublicProfile(): bool
3590  {
3591  return in_array($this->getPref('public_profile'), ['y', 'g']);
3592  }
3593 
3597  public function getPublicName(): string
3598  {
3599  if ($this->hasPublicProfile()) {
3600  return $this->getFirstname() . ' ' . $this->getLastname() . ' (' . $this->getLogin() . ')';
3601  } else {
3602  return $this->getLogin();
3603  }
3604  }
3605 
3606  public static function _writeHistory(
3607  int $a_usr_id,
3608  string $a_login
3609  ): void {
3610  global $DIC;
3611 
3612  $ilDB = $DIC['ilDB'];
3613 
3614  $timestamp = time();
3615 
3616  $res = $ilDB->queryF(
3617  'SELECT * FROM loginname_history WHERE usr_id = %s AND login = %s AND history_date = %s',
3618  ['integer', 'text', 'integer'],
3619  [$a_usr_id, $a_login, $timestamp]
3620  );
3621 
3622  if ($ilDB->numRows($res) == 0) {
3623  $ilDB->manipulateF(
3624  '
3625  INSERT INTO loginname_history
3626  (usr_id, login, history_date)
3627  VALUES (%s, %s, %s)',
3628  ['integer', 'text', 'integer'],
3629  [$a_usr_id, $a_login, $timestamp]
3630  );
3631  }
3632  }
3633 
3638  public static function _getUsersOnline(
3639  int $a_user_id = 0,
3640  bool $a_no_anonymous = false
3641  ): array {
3642  global $DIC;
3643 
3644  $ilDB = $DIC->database();
3645 
3646  $log = ilLoggerFactory::getLogger('user');
3647 
3648  $pd_set = new ilSetting('pd');
3649  $atime = $pd_set->get('user_activity_time') * 60;
3650  $ctime = time();
3651 
3652  $where = [];
3653 
3654  if ($a_user_id === 0) {
3655  $where[] = 'user_id > 0';
3656  } else {
3657  $where[] = 'user_id = ' . $ilDB->quote($a_user_id, 'integer');
3658  }
3659 
3660  if ($a_no_anonymous) {
3661  $where[] = 'user_id != ' . $ilDB->quote(ANONYMOUS_USER_ID, 'integer');
3662  }
3663 
3664  if (ilUserAccountSettings::getInstance()->isUserAccessRestricted()) {
3665  $where[] = $ilDB->in('time_limit_owner', ilUserFilter::getInstance()->getFolderIds(), false, 'integer');
3666  }
3667 
3668  $where[] = 'expires > ' . $ilDB->quote($ctime, 'integer');
3669  $where[] = '(p.value IS NULL OR NOT p.value = ' . $ilDB->quote('y', 'text') . ')';
3670 
3671  $where = 'WHERE ' . implode(' AND ', $where);
3672 
3673  $r = $ilDB->queryF(
3674  $q = "
3675  SELECT COUNT(user_id) num, user_id, firstname, lastname, title, login, last_login, MAX(ctime) ctime, context, agree_date
3676  FROM usr_session
3677  LEFT JOIN usr_data u
3678  ON user_id = u.usr_id
3679  LEFT JOIN usr_pref p
3680  ON (p.usr_id = u.usr_id AND p.keyword = %s)
3681  {$where}
3682  GROUP BY user_id, firstname, lastname, title, login, last_login, context, agree_date
3683  ORDER BY lastname, firstname
3684  ",
3685  ['text'],
3686  ['hide_own_online_status']
3687  );
3688 
3689  $log->debug('Query: ' . $q);
3690 
3691  $users = [];
3692  while ($user = $ilDB->fetchAssoc($r)) {
3693  if ($atime <= 0 || $user['ctime'] + $atime > $ctime) {
3694  $users[$user['user_id']] = $user;
3695  }
3696  }
3697 
3698  $log->debug('Found users: ' . count($users));
3699 
3700  $hide_users = $DIC['legalDocuments']->usersWithHiddenOnlineStatus(array_map(intval(...), array_column($users, 'user_id')));
3701  $users = array_filter(
3702  $users,
3703  fn($user) => !in_array((int) $user['user_id'], $hide_users, true)
3704  );
3705 
3706  return $users;
3707  }
3708 
3713  public static function _generateRegistrationHash(int $a_usr_id): string
3714  {
3715  global $DIC;
3716 
3717  $ilDB = $DIC['ilDB'];
3718 
3719  do {
3720  $continue = false;
3721 
3722  $hashcode = substr(md5(uniqid(mt_rand(), true)), 0, 16);
3723 
3724  $res = $ilDB->queryf(
3725  '
3726  SELECT COUNT(usr_id) cnt FROM usr_data
3727  WHERE reg_hash = %s',
3728  ['text'],
3729  [$hashcode]
3730  );
3731  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
3732  if ($row->cnt > 0) {
3733  $continue = true;
3734  }
3735  break;
3736  }
3737 
3738  if ($continue) {
3739  continue;
3740  }
3741 
3742  $ilDB->manipulateF(
3743  '
3744  UPDATE usr_data
3745  SET reg_hash = %s
3746  WHERE usr_id = %s',
3747  ['text', 'integer'],
3748  [$hashcode, $a_usr_id]
3749  );
3750 
3751  break;
3752  } while (true);
3753 
3754  return $hashcode;
3755  }
3756 
3762  public static function _verifyRegistrationHash(
3763  string $a_hash
3764  ): int {
3765  global $DIC;
3766 
3767  $ilDB = $DIC['ilDB'];
3768 
3769  $res = $ilDB->queryf(
3770  '
3771  SELECT usr_id, create_date FROM usr_data
3772  WHERE reg_hash = %s',
3773  ['text'],
3774  [$a_hash]
3775  );
3776  while ($row = $ilDB->fetchAssoc($res)) {
3777  $oRegSettigs = new ilRegistrationSettings();
3778 
3779  if ($oRegSettigs->getRegistrationHashLifetime() != 0 &&
3780  time() - $oRegSettigs->getRegistrationHashLifetime() > strtotime($row['create_date'])) {
3782  'reg_confirmation_hash_life_time_expired',
3783  (int) $row['usr_id']
3784  );
3785  }
3786 
3787  $ilDB->manipulateF(
3788  '
3789  UPDATE usr_data
3790  SET reg_hash = %s
3791  WHERE usr_id = %s',
3792  ['text', 'integer'],
3793  ['', (int) $row['usr_id']]
3794  );
3795 
3796  return (int) $row['usr_id'];
3797  }
3798 
3799  throw new ilRegistrationHashNotFoundException('reg_confirmation_hash_not_found');
3800  }
3801 
3802  public function setBirthday(?string $a_birthday): void
3803  {
3804  if ($a_birthday && strlen($a_birthday)) {
3805  $date = new ilDate($a_birthday, IL_CAL_DATE);
3806  $this->birthday = $date->get(IL_CAL_DATE);
3807  } else {
3808  $this->birthday = null;
3809  }
3810  }
3811 
3812  public function getBirthday(): ?string
3813  {
3814  return $this->birthday;
3815  }
3816 
3823  public static function getUserIdsByInactivityPeriod(
3824  int $periodInDays
3825  ): array {
3826  global $DIC;
3827 
3828  if ($periodInDays < 1) {
3829  throw new ilException('Invalid period given');
3830  }
3831 
3832  $date = date('Y-m-d H:i:s', (time() - ($periodInDays * 24 * 60 * 60)));
3833 
3834  $query = 'SELECT usr_id FROM usr_data WHERE last_login IS NOT NULL AND last_login < %s';
3835 
3836  $ids = [];
3837 
3838  $types = ['timestamp'];
3839  $values = [$date];
3840 
3841  $res = $DIC->database()->queryF($query, $types, $values);
3842  while ($row = $DIC->database()->fetchAssoc($res)) {
3843  $ids[] = (int) $row['usr_id'];
3844  }
3845 
3846  return $ids;
3847  }
3848 
3854  public static function getUserIdsNeverLoggedIn(
3855  int $thresholdInDays
3856  ): array {
3857  global $DIC;
3858 
3859  $date = date('Y-m-d H:i:s', (time() - ($thresholdInDays * 24 * 60 * 60)));
3860 
3861  $query = 'SELECT usr_id FROM usr_data WHERE last_login IS NULL AND create_date < %s';
3862 
3863  $ids = [];
3864 
3865  $types = ['timestamp'];
3866  $values = [$date];
3867 
3868  $res = $DIC->database()->queryF($query, $types, $values);
3869  while ($row = $DIC->database()->fetchAssoc($res)) {
3870  $ids[] = (int) $row['usr_id'];
3871  }
3872 
3873  return $ids;
3874  }
3875 
3882  public static function _getUserIdsByInactivationPeriod(
3883  int $period
3884  ): array {
3886  $field = 'inactivation_date';
3888 
3889  if (!$period) {
3890  throw new ilException('no valid period given');
3891  }
3892 
3893  global $DIC;
3894 
3895  $ilDB = $DIC['ilDB'];
3896 
3897  $date = date('Y-m-d H:i:s', (time() - ($period * 24 * 60 * 60)));
3898 
3899  $query = "SELECT usr_id FROM usr_data WHERE $field < %s AND active = %s";
3900 
3901  $res = $ilDB->queryF($query, ['timestamp', 'integer'], [$date, 0]);
3902 
3903  $ids = [];
3904  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
3905  $ids[] = (int) $row->usr_id;
3906  }
3907 
3908  return $ids;
3909  }
3910 
3911  public function resetOwner(): void
3912  {
3913  $ilDB = $this->db;
3914 
3915  $query = 'UPDATE object_data SET owner = 0 ' .
3916  'WHERE owner = ' . $ilDB->quote($this->getId(), 'integer');
3917  $ilDB->query($query);
3918  }
3919 
3924  public static function getFirstLettersOfLastnames(
3925  ?array $user_ids = null
3926  ): array {
3927  global $DIC;
3928 
3929  $ilDB = $DIC->database();
3930 
3931  $q = 'SELECT DISTINCT ' . $ilDB->upper($ilDB->substr('lastname', 1, 1)) . ' let' .
3932  ' FROM usr_data' .
3933  ' WHERE usr_id <> ' . $ilDB->quote(ANONYMOUS_USER_ID, 'integer') .
3934  ($user_ids !== null ? ' AND ' . $ilDB->in('usr_id', $user_ids, false, 'integer') : '') .
3935  ' ORDER BY let';
3936  $let_set = $ilDB->query($q);
3937 
3938  $let = [];
3939  while ($let_rec = $ilDB->fetchAssoc($let_set)) {
3940  $let[$let_rec['let']] = $let_rec['let'];
3941  }
3942  return $let;
3943  }
3944 
3945  public static function userExists(
3946  array $a_usr_ids = []
3947  ): bool {
3948  global $DIC;
3949 
3950  $ilDB = $DIC['ilDB'];
3951 
3952  $query = 'SELECT count(*) num FROM object_data od ' .
3953  'JOIN usr_data ud ON obj_id = usr_id ' .
3954  'WHERE ' . $ilDB->in('obj_id', $a_usr_ids, false, 'integer') . ' ';
3955  $res = $ilDB->query($query);
3956  $num_rows = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)->num;
3957  return $num_rows == count($a_usr_ids);
3958  }
3959 
3960  public function exportPersonalData(): void
3961  {
3962  if (!isset($this->user)) {
3963  global $DIC;
3964  $this->user = $DIC->user();
3965  }
3966  $export_consumer = (new ExportFactory())->consumer()->handler();
3967  $configs = $export_consumer->exportConfig()->allExportConfigs();
3969  $config = $configs->getElementByClassName('ilUserExportConfig');
3970  $config->setExportType('personal_data');
3971  $export = $export_consumer->createStandardExportByObject(
3972  $this->user->getId(),
3973  $this,
3974  $configs
3975  );
3976  $stream = Streams::ofString($export->getIRSSInfo()->getStream()->getContents());
3977  $file_name = $export->getIRSSInfo()->getFileName();
3978  $export->getIRSS()->delete($export_consumer->exportStakeholderHandler());
3979  $this->delivery->deliver($stream, $file_name);
3980  }
3981 
3982  public function getPersonalDataExportFile(): string
3983  {
3984  $dir = ilExport::_getExportDirectory($this->getId(), 'xml', 'usr', 'personal_data');
3985  if (!is_dir($dir)) {
3986  return '';
3987  }
3988  foreach (ilFileUtils::getDir($dir) as $entry) {
3989  if (is_int(strpos($entry['entry'], '.zip'))) {
3990  return $entry['entry'];
3991  }
3992  }
3993 
3994  return '';
3995  }
3996 
3997  public function sendPersonalDataFile(): void
3998  {
3999  $file = ilExport::_getExportDirectory($this->getId(), 'xml', 'usr', 'personal_data') .
4000  '/' . $this->getPersonalDataExportFile();
4001  if (is_file($file)) {
4003  }
4004  }
4005 
4006  public function importPersonalData(
4007  array $a_file,
4008  bool $a_profile_data,
4009  bool $a_settings,
4010  bool $a_notes,
4011  bool $a_calendar
4012  ): void {
4013  $imp = new ilImport();
4014  // bookmarks need to be skipped, importer does not exist anymore
4015  $imp->addSkipImporter('components/ILIAS/Bookmarks');
4016  if (!$a_profile_data) {
4017  $imp->addSkipEntity('components/ILIAS/User', 'usr_profile');
4018  }
4019  if (!$a_settings) {
4020  $imp->addSkipEntity('components/ILIAS/User', 'usr_setting');
4021  }
4022  if (!$a_notes) {
4023  $imp->addSkipEntity('components/ILIAS/Notes', 'user_notes');
4024  }
4025  if (!$a_calendar) {
4026  $imp->addSkipEntity('components/ILIAS/Calendar', 'calendar');
4027  }
4028  $imp->importEntity(
4029  $a_file['tmp_name'],
4030  $a_file['name'],
4031  'usr',
4032  'components/ILIAS/User'
4033  );
4034  }
4035 
4036  public function setInactivationDate(?string $inactivation_date): void
4037  {
4038  $this->inactivation_date = $inactivation_date;
4039  }
4040 
4041  public function getInactivationDate(): ?string
4042  {
4043  return $this->inactivation_date;
4044  }
4045 
4046  public function isAnonymous(): bool
4047  {
4048  return self::_isAnonymous($this->getId());
4049  }
4050 
4051  public static function _isAnonymous(int $usr_id): bool
4052  {
4053  return $usr_id == ANONYMOUS_USER_ID;
4054  }
4055 
4056  public function activateDeletionFlag(): void
4057  {
4058  $this->writePref('delete_flag', true);
4059  }
4060 
4061  public function removeDeletionFlag(): void
4062  {
4063  $this->writePref('delete_flag', false);
4064  }
4065 
4066  public function hasDeletionFlag(): bool
4067  {
4068  return (bool) $this->getPref('delete_flag');
4069  }
4070 
4071  public function setIsSelfRegistered(bool $status): void
4072  {
4073  $this->is_self_registered = $status;
4074  }
4075 
4076  public function isSelfRegistered(): bool
4077  {
4079  }
4080 
4081 
4082  //
4083  // MULTI-TEXT / INTERESTS
4084  //
4085 
4089  public function setGeneralInterests(?array $value = null): void
4090  {
4091  $this->interests_general = $value ?? [];
4092  }
4093 
4097  public function getGeneralInterests(): array
4098  {
4099  return $this->interests_general;
4100  }
4101 
4105  public function getGeneralInterestsAsText(): string
4106  {
4107  return $this->buildTextFromArray($this->interests_general);
4108  }
4109 
4113  public function setOfferingHelp(?array $value = null): void
4114  {
4115  $this->interests_help_offered = $value ?? [];
4116  }
4117 
4121  public function getOfferingHelp(): array
4122  {
4124  }
4125 
4129  public function getOfferingHelpAsText(): string
4130  {
4131  return $this->buildTextFromArray($this->interests_help_offered);
4132  }
4133 
4137  public function setLookingForHelp(?array $value = null): void
4138  {
4139  $this->interests_help_looking = $value ?? [];
4140  }
4141 
4145  public function getLookingForHelp(): array
4146  {
4148  }
4149 
4153  public function getLookingForHelpAsText(): string
4154  {
4155  return $this->buildTextFromArray($this->interests_help_looking);
4156  }
4157 
4163  protected function buildTextFromArray(array $a_attr): string
4164  {
4165  if (count($a_attr) > 0) {
4166  return implode(', ', $a_attr);
4167  }
4168  return '';
4169  }
4170 
4171  protected function readMultiTextFields(): void
4172  {
4173  global $DIC;
4174 
4175  $ilDB = $DIC['ilDB'];
4176 
4177  if (!$this->getId()) {
4178  return;
4179  }
4180 
4181  $set = $ilDB->query('SELECT field_id,value' .
4182  ' FROM usr_data_multi' .
4183  ' WHERE usr_id = ' . $ilDB->quote($this->getId(), 'integer') .
4184  ' ORDER BY value');
4185  while ($row = $ilDB->fetchAssoc($set)) {
4186  $values[$row['field_id']][] = $row['value'];
4187  }
4188 
4189  if (isset($values['interests_general'])) {
4190  $this->setGeneralInterests($values['interests_general']);
4191  } else {
4192  $this->setGeneralInterests();
4193  }
4194  if (isset($values['interests_help_offered'])) {
4195  $this->setOfferingHelp($values['interests_help_offered']);
4196  } else {
4197  $this->setOfferingHelp();
4198  }
4199  if (isset($values['interests_help_looking'])) {
4200  $this->setLookingForHelp($values['interests_help_looking']);
4201  } else {
4202  $this->setLookingForHelp();
4203  }
4204  }
4205 
4206  public function updateMultiTextFields(bool $a_create = false): void
4207  {
4208  global $DIC;
4209 
4210  $ilDB = $DIC['ilDB'];
4211 
4212  if (!$this->getId()) {
4213  return;
4214  }
4215 
4216  if (!$a_create) {
4217  $this->deleteMultiTextFields();
4218  }
4219 
4220  $map = [
4221  'interests_general' => $this->getGeneralInterests(),
4222  'interests_help_offered' => $this->getOfferingHelp(),
4223  'interests_help_looking' => $this->getLookingForHelp()
4224  ];
4225 
4226  foreach ($map as $id => $values) {
4227  if (is_array($values) && count($values)) {
4228  foreach ($values as $value) {
4229  $value = trim($value);
4230  if ($value) {
4231  $uniq_id = $ilDB->nextId('usr_data_multi');
4232 
4233  $ilDB->manipulate('INSERT usr_data_multi' .
4234  ' (id,usr_id,field_id,value) VALUES' .
4235  ' (' . $ilDB->quote($uniq_id, 'integer') .
4236  ',' . $ilDB->quote($this->getId(), 'integer') .
4237  ',' . $ilDB->quote($id, 'text') .
4238  ',' . $ilDB->quote($value, 'text') .
4239  ')');
4240  }
4241  }
4242  }
4243  }
4244  }
4245 
4246  protected function deleteMultiTextFields(): void
4247  {
4248  global $DIC;
4249 
4250  $ilDB = $DIC['ilDB'];
4251 
4252  if (!$this->getId()) {
4253  return;
4254  }
4255 
4256  $ilDB->manipulate('DELETE FROM usr_data_multi' .
4257  ' WHERE usr_id = ' . $ilDB->quote($this->getId(), 'integer'));
4258  }
4259 
4260  public static function findInterests(
4261  string $a_term,
4262  ?int $a_user_id = null,
4263  ?string $a_field_id = null
4264  ): array {
4265  global $DIC;
4266 
4267  $ilDB = $DIC['ilDB'];
4268 
4269  $res = [];
4270 
4271  $sql = 'SELECT DISTINCT(value)' .
4272  ' FROM usr_data_multi' .
4273  ' WHERE ' . $ilDB->like('value', 'text', '%' . $a_term . '%');
4274  if ($a_field_id) {
4275  $sql .= ' AND field_id = ' . $ilDB->quote($a_field_id, 'text');
4276  }
4277  if ($a_user_id) {
4278  $sql .= ' AND usr_id <> ' . $ilDB->quote($a_user_id, 'integer');
4279  }
4280  $sql .= ' ORDER BY value';
4281  $set = $ilDB->query($sql);
4282  while ($row = $ilDB->fetchAssoc($set)) {
4283  $res[] = $row['value'];
4284  }
4285 
4286  return $res;
4287  }
4288 
4297  public static function getProfileStatusOfUsers(
4298  array $a_user_ids
4299  ): array {
4300  global $DIC;
4301 
4302  $ilDB = $DIC->database();
4303 
4304  $set = $ilDB->query(
4305  'SELECT * FROM usr_pref ' .
4306  ' WHERE keyword = ' . $ilDB->quote('public_profile', 'text') .
4307  ' AND ' . $ilDB->in('usr_id', $a_user_ids, false, 'integer')
4308  );
4309  $r = [
4310  'global' => [],
4311  'local' => [],
4312  'public' => [],
4313  'not_public' => []
4314  ];
4315  while ($rec = $ilDB->fetchAssoc($set)) {
4316  if ($rec['value'] == 'g') {
4317  $r['global'][] = $rec['usr_id'];
4318  $r['public'][] = $rec['usr_id'];
4319  }
4320  if ($rec['value'] == 'y') {
4321  $r['local'][] = $rec['usr_id'];
4322  $r['public'][] = $rec['usr_id'];
4323  }
4324  }
4325  foreach ($a_user_ids as $id) {
4326  if (!in_array($id, $r['public'])) {
4327  $r['not_public'][] = $id;
4328  }
4329  }
4330 
4331  return $r;
4332  }
4333 }
getCurrentLanguage()
returns the current language (may differ from user&#39;s pref setting!)
static getWebspaceDir(string $mode="filesystem")
get webspace directory
static hasActiveSession(int $a_user_id, string $a_session_id)
setUTitle(string $a_str)
set user title (note: don&#39;t mix up this method with setTitle() that is derived from ilObject and sets...
setProfileIncomplete(bool $a_prof_inc)
string $passwd
string $loc_zoom
static get(string $a_var)
setTimeLimitUnlimited(bool $a_unlimited)
static array static setUseRelativeDates(bool $a_status)
set use relative dates
static _setFeedPass(int $a_user_id, string $a_password)
Set news feed password for user.
setClientIP(string $a_str)
setAvatarRid(?string $avatar_rid)
string $avatar_rid
$res
Definition: ltiservices.php:66
getStoredActive(int $a_id)
get user active state
setLastLogin(string $a_str)
static _getUsersForRole(int $role_id, int $active=-1)
return array of complete users which belong to a specific role
resetPassword(string $raw, string $raw_retype)
Resets the user password.
refreshLogin()
updates the login data of a &#39;user&#39;
static _getLoginAttempts(int $a_usr_id)
static _destroyByUserId(int $a_user_id)
Destroy session.
static copyProfilePicturesToDirectory(int $a_user_id, string $a_dir)
static _deleteUser(int $a_usr_id)
getPersonalPicturePath(string $a_size='small', bool $a_force_pic=false)
static _lookupLanguage(int $a_usr_id)
buildTextFromArray(array $a_attr)
Convert multi-text values to plain text.
string $utitle
const IL_INST_ID
Definition: constants.php:40
const IL_CAL_DATETIME
const ANONYMOUS_USER_ID
Definition: constants.php:27
static getLogger(string $a_component_id)
Get component logger.
static _getAllUserData(?array $a_fields=null, int $active=-1)
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 _getAuthMode(?string $a_auth_mode)
writePref(string $a_keyword, string $a_value)
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
setAgreeDate(?string $a_str)
array $interests_help_looking
static styleExists(string $style_id)
static getUserIdsByInactivityPeriod(int $periodInDays)
Get ids of all users that have been inactive for at least the given period.
string $street
static lookupMatriculation(int $a_usr_id)
static getFirstLettersOfLastnames(?array $user_ids=null)
Get first letters of all lastnames.
string $fullname
__construct(int $a_user_id=0, bool $a_call_by_reference=false)
static getProfileStatusOfUsers(array $a_user_ids)
Get profile status.
static _verifyRegistrationHash(string $a_hash)
Verifies a registration hash.
assignData(array $a_data)
loads a record &#39;user&#39; from array
fetchAssoc(ilDBStatement $statement)
static _externalAccountExists(string $a_external_account, string $a_auth_mode)
Check if an external account name already exists.
setMatriculation(string $a_str)
static _lookupFullname(int $a_user_id)
getGeneralInterestsAsText()
Get general interests as plain text.
getDefaultLanguage()
Return default language.
Class for user related exception handling in ILIAS.
setPhoneOffice(string $a_str)
addToPCClipboard(string $a_content, string $a_time, int $a_nr)
Add a page content item to PC clipboard (should go to another class)
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
static _moveUsersToStyle(string $a_from_skin, string $a_from_style, string $a_to_skin, string $a_to_style)
static _getPreferences(int $user_id)
get preferences for user
removeObjectFromClipboard(int $a_item_id, string $a_type)
getPasswordPolicyResetStatus()
static _removeTrackingDataForUser(int $user_id)
to be called from IlObjUser
const SYSTEM_USER_ID
This file contains constants for PHPStan analyis, see: https://phpstan.org/config-reference#constants...
Definition: constants.php:26
updateLogin(string $a_login)
update login name
setSelectedCountry(string $a_val)
Set selected country (selection drop down)
deletePref(string $a_keyword)
static _lookupLastLogin(int $a_user_id)
array $interests_help_offered
string $phone_mobile
int $time_limit_from
string $time_limit_message
static array $personal_image_cache
setFullname()
builds a string with title + firstname + lastname method is used to build fullname in member variable...
const PASSWD_PLAIN
ilTree $tree
string $matriculation
static _writeAuthMode(int $a_usr_id, string $a_auth_mode)
static _lookupName(int $a_user_id)
lookup user name
static resetToDefaults()
reset to defaults
Import class.
static _lookupId($a_user_str)
static lookupTitle(int $a_page_id)
static _deleteSettingsOfUser(int $a_user)
getFullname(int $a_max_strlen=0)
string $passwd_type
removeUserPicture(bool $a_do_update=true)
static getUserIdsByEmail(string $a_email)
int $time_limit_until
static _lookupPref(int $a_usr_id, string $a_keyword)
addObjectToClipboard(int $a_item_id, string $a_type, string $a_title, int $a_parent=0, string $a_time='', int $a_order_nr=0)
add an item to user&#39;s personal clipboard
loadLanguageModule(string $a_module)
static _checkExternalAuthAccount(string $a_auth, string $a_account, bool $tryFallback=true)
check whether external account and authentication method matches with a user
static getUserSubsetByPreferenceValue(array $a_user_ids, string $a_keyword, string $a_val)
For a given set of user IDs return a subset that has a given user preference set. ...
string $longitude
getCreateDate()
Get create date in YYYY-MM-DD HH-MM-SS format.
static _lookupExternalAccount(int $a_user_id)
static _getUsersForGroup(array $a_mem_ids, int $active=-1)
return user data for group members
static _deleteByUser(int $a_usr_id)
static _needsExternalAccountByAuthMode($a_auth_mode)
Check if chosen auth mode needs an external account entry.
string $institution
const IL_CAL_UNIX
static setLanguage(ilLanguage $a_lng)
static _lookupAuthMode(int $a_usr_id)
login()
description: > Example for rendring a login glyph.
Definition: login.php:41
setPasswordSalt(?string $password_salt)
static lookupOrgUnitsRepresentation(int $a_usr_id)
lookup org unit representation
static _lookupGender(int $a_user_id)
setTimeLimitUntil(?int $a_until)
static _getAuthModeName($a_auth_key)
static _uploadPersonalPicture(string $tmp_file, int $obj_id)
Create a personal picture image file from a temporary image file.
setLoginAttempts(int $a_login_attempts)
static now()
Return current timestamp in Y-m-d H:i:s format.
static _deleteAllPref(int $a_user_id)
Deletes a userpref value of the user from the database.
static _getExportDirectory(int $a_obj_id, string $a_type="xml", string $a_obj_type="", string $a_entity="")
Get export directory for an repository object
string $latitude
setInstitution(string $a_str)
setCity(string $a_str)
getPublicName()
returns firstname lastname and login if profile is public, login otherwise
deleteUserDefinedFieldEntries()
Services $irss
getAuthMode(bool $a_auth_key=false)
static _deleteUser(int $a_usr_id)
getOfferingHelpAsText()
Get help offering as plain text.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$ilErr
Definition: raiseError.php:33
setLatitude(?string $a_latitude)
setComment(string $a_str)
setPasswd(string $a_str, string $a_type=ilObjUser::PASSWD_PLAIN)
setGender(string $a_str)
int $last_password_change_ts
setId(int $id)
static _getAvatar(int $a_usr_id)
Factory for Date Formats.
Definition: Factory.php:26
setExternalAccount(string $a_str)
static _getNumberOfUsersForStyle(string $a_skin, string $a_style)
static deliverFileLegacy(string $a_file, ?string $a_filename=null, ?string $a_mime=null, ?bool $isInline=false, ?bool $removeAfterDelivery=false, ?bool $a_exit_after=true)
string $agree_date
setPasswordPolicyResetStatus(bool $status)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
array $user_defined_data
setBirthday(?string $a_birthday)
bool $profile_incomplete
string $department
setSkin(string $a_str)
static _writeExternalAccount(int $a_usr_id, string $a_ext_id)
string $password_salt
static _getInstance()
Get singleton instance of this class.
string $last_login
bool $time_limit_unlimited
static _getExternalAccountsByAuthMode(string $a_auth_mode, bool $a_read_auth_default=false)
Get list of external account by authentication method Note: If login == ext_account for two user with...
static getUserIdByLogin(string $a_login)
writeAccepted()
write accept date of user agreement
static _getLastHistoryDataByUserId(int $a_usr_id)
Returns the last used loginname and the changedate of the passed user_id.
ilAppEventHandler $app_event_handler
string $auth_mode
setLogin(string $a_str)
setActive(bool $a_active, int $a_owner=0)
set user active state and updates system fields appropriately
const NO_AVATAR_RID
txt(string $a_topic, string $a_default_lang_fallback_mod="")
const int AUTH_LOCAL
string $phone_home
getClipboardObjects(string $a_type='', bool $a_top_nodes_only=false)
get all clipboard objects of user and specified type
static userExists(array $a_usr_ids=[])
static _lookupClientIP(int $a_user_id)
setDepartment(string $a_str)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupTitle(int $obj_id)
static deleteEntriesOfUser(int $a_user_id)
$GLOBALS["DIC"]
Definition: wac.php:53
string $last_update
setOfferingHelp(?array $value=null)
static getLoginFromAuth()
Gets the username from $ilAuth, and converts it into an ILIAS login name.
clipboardDeleteObjectsOfType(string $a_type)
static getUserLoginsByEmail(string $a_email)
getLoginByUserId(int $a_userid)
This describes how a letter or a picture avatar could be modified during construction of UI...
Definition: Avatar.php:28
A Date Format provides a format definition akin to PHP&#39;s date formatting options, but stores the sing...
Definition: DateFormat.php:26
static _getFeedPass(int $a_user_id)
Lookup news feed password for user.
static _exists(string $a_parent_type, int $a_id, string $a_lang="", bool $a_no_cache=false)
Checks whether page exists.
static _generateRegistrationHash(int $a_usr_id)
Generates a unique hashcode for activating a user profile after registration.
static styleExistsForSkinId(string $skin_id, string $style_id)
setApproveDate(?string $a_str)
set date the user account was activated null indicates that the user has not yet been activated ...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _setUserInactive(int $a_usr_id)
ilLanguage $lng
setPhoneHome(string $a_str)
static _getNumberOfUsersPerAuthMode()
get number of users per auth mode
static _toggleActiveStatusOfUsers(array $a_usr_ids, bool $a_status)
static _loginExists(string $a_login, int $a_user_id=0)
check if a login name already exists You may exclude a user from the check by giving his user id as 2...
static removeForUser(int $user_id)
Remove all notifications for given user.
getPref(string $a_keyword)
ilDBInterface $db
setInactivationDate(?string $inactivation_date)
syncActive()
synchronizes current and stored user active values for the owner value to be set correctly, this function should only be called when an admin is approving a user account
static _getUsersOnline(int $a_user_id=0, bool $a_no_anonymous=false)
reads all active sessions from db and returns users that are online OR returns only one active user i...
string $second_email
global $DIC
Definition: shib_login.php:26
string $birthday
updateOwner()
update owner of object in db
static _deletePref(int $a_user_id, string $a_keyword)
static _getUserData(array $a_internalids)
return user data for given user ids
checkUserId()
check user id with login name
Class ilObjForumAdministration.
string $country
static _writeHistory(int $a_usr_id, string $a_login)
getLookingForHelpAsText()
Get help looking for as plain text.
setHobby(string $a_str)
setIsSelfRegistered(bool $status)
static getDir(string $a_dir, bool $a_rec=false, ?string $a_sub_dir="")
get directory
string $phone_office
static _lookupFields(int $a_user_id)
lookup fields (deprecated; use more specific methods instead)
bool $passwd_policy_reset
setPref(string $a_keyword, ?string $a_value)
Class ilUserAvatarResolver.
const UDF_TYPE_WYSIWYG
static _getUserIdsByInactivationPeriod(int $period)
get ids of all users that have been inactivated since at least the given period
setFirstLogin(string $a_str)
string $gender
setCountry(string $a_str)
setEmail(string $a_str)
setFax(string $a_str)
queryF(string $query, array $types, array $values)
getPCClipboardContent()
Add a page content item to PC clipboard (should go to another class)
static _isAnonymous(int $usr_id)
existsPref(string $a_keyword)
importPersonalData(array $a_file, bool $a_profile_data, bool $a_settings, bool $a_notes, bool $a_calendar)
const PASSWD_CRYPTED
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:70
int $time_limit_owner
setPhoneMobile(string $a_str)
string $first_login
getSelectedCountry()
Get selected country (selection drop down)
static deleteByUserId(int $a_user_id)
setLastPasswordChangeTS(int $a_last_password_change_ts)
setLastname(string $a_str)
setPasswordEncodingType(?string $password_encryption_type)
ILIAS FileDelivery Delivery StreamDelivery $delivery
static _getPersonalPicturePath(int $a_usr_id, string $a_size='small', bool $a_force_pic=false, bool $a_prevent_no_photo_image=false, bool $html_export=false)
setStreet(string $a_str)
string $lastname
static _doesLoginnameExistInHistory(string $a_login)
Checks whether the passed loginname already exists in history.
static _getUsersForClipboadObject(string $a_type, int $a_id)
get all users, that have a certain object within their clipboard
static deleteUserPortfolios(int $a_user_id)
Delete all portfolio data for user.
Class ilObjAuthSettingsGUI.
bool $is_self_registered
static findInterests(string $a_term, ?int $a_user_id=null, ?string $a_field_id=null)
static skinExists(string $skin_id, ?ilSystemStyleConfig $system_style_config=null)
Check whether a skin exists.
const IL_CAL_DATE
string $ext_account
static _incrementLoginAttempts(int $a_usr_id)
string $last_profile_prompt
static _lookupFeedHash(int $user_id, bool $create=false)
Lookup news feed hash for user.
setLastProfilePrompt(string $a_str)
static _getImportedUserId(string $i2_id)
static _getUsersForFolder(int $ref_id, int $active)
get users for a category or from system folder
setLanguage(string $a_str)
static _readUsersProfileData(array $a_user_ids)
global $ilSetting
Definition: privfeed.php:31
static _lookup(int $a_user_id, string $a_field)
static __extractId(string $ilias_id, int $inst_id)
extract ref id from role title, e.g.
string $org_units
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
static toUsernameWithoutDomain(string $a_login)
Static function removes Microsoft domain name from username webdav related.
__construct(Container $dic, ilPlugin $plugin)
setTimeLimitOwner(int $a_owner)
updateMultiTextFields(bool $a_create=false)
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ?ilObjUser $user=null,)
$q
Definition: shib_logout.php:23
setSecondEmail(?string $second_email)
string $password_encoding_type
static _writePref(int $a_usr_id, string $a_keyword, string $a_value)
setLongitude(?string $a_longitude)
array $interests_general
setLocationZoom(?int $a_locationzoom)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ilLogger $log
DateFormatFactory $date_format_factory
setLastPasswordChangeToNow()
string $approve_date
setZipcode(string $a_str)
ilCronDeleteInactiveUserReminderMail $cron_delete_user_reminder_mail
setTimeLimitMessage(string $a_time_limit_message)
static _lookupFirstLogin(int $a_user_id)
debug(string $message, array $context=[])
Class for user related exception handling in ILIAS.
string $client_ip
setUserDefinedData(array $a_data)
static _lookupType(int $id, bool $reference=false)
string $zipcode
setGeneralInterests(?array $value=null)
setTimeLimitFrom(?int $a_from)
getClipboardChilds(int $a_parent, string $a_insert_time)
Get children of an item.
string $referral_comment
setFirstname(string $a_str)
string $inactivation_date
static _lookupEmail(int $a_user_id)
string $sel_country
static clear(string $a_var)
static _getInstance()
Get instance of ilSecuritySettings.
string $firstname
static set(string $a_var, $a_val)
Set a value.
static _getUsersForIds(array $a_mem_ids, int $active=-1, int $timelimitowner=-1)
return user data for given user id
setAuthMode(?string $a_str)
setCurrentLanguage(string $a_val)
Set current language.
static _lookupActive(int $a_usr_id)
hasPublicProfile()
returns true if public is profile, false otherwise
static _getAllUserAssignedStyles()
setLastUpdate(string $a_str)
static getUserIdsNeverLoggedIn(int $thresholdInDays)
Get ids of all users that have never logged in.
setOwner(int $usr_id)
static _removeTrackingDataForUser(int $user_id)
static formatPeriod(ilDateTime $start, ilDateTime $end, bool $a_skip_starting_day=false, ?ilObjUser $user=null)
Format a period of two dates Shows: 14.
static _getLocalAccountsForEmail(string $a_email)
clipboardHasObjectsOfType(string $a_type)
Check whether clipboard has objects of a certain type.
ilObjUser $user
$r
static _lookupLogin(int $a_user_id)
setLookingForHelp(?array $value=null)