ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilObjUser.php
Go to the documentation of this file.
1<?php
2
21use ILIAS\User\Profile\DataRepository as ProfileDataRepository;
22use ILIAS\User\Profile\Fields\ConfigurationRepository as ProfileConfigurationRepository;
33use ILIAS\Data\Factory as DataFactory;
35use ILIAS\Export\ExportHandler\Factory as ExportFactory;
38
45class ilObjUser extends ilObject
46{
47 public const PASSWD_PLAIN = 'plain';
48 public const PASSWD_CRYPTED = 'crypted';
49
50 public const DATABASE_DATE_FORMAT = 'Y-m-d H:i:s';
51
52 private string $ext_account = '';
53 private string $fullname;
54 private bool $time_limit_unlimited = false;
55 private ?int $time_limit_until = null;
56 private ?int $time_limit_from = null;
57 private int $time_limit_owner = 7;
58 private string $last_login = '';
59 private string $passwd = '';
60 private string $passwd_type = '';
61 private ?string $password_encoding_type = null;
62 private ?string $password_salt = null;
63 private ?string $approve_date = null;
64 private ?string $agree_date = null;
65 private int $active = 0;
66 private string $client_ip = ''; // client ip to check before login
67 private ?string $auth_mode = null; // authentication mode
68 private int $last_password_change_ts = 0;
69 private bool $passwd_policy_reset = false;
70 private int $login_attempts = 0;
72 private array $prefs = [];
73 private static array $personal_image_cache = [];
74 private ?string $inactivation_date = null;
75 private bool $is_self_registered = false; // flag for self registered users
76 private string $last_profile_prompt = ''; // timestamp
77 private string $first_login = ''; // timestamp
78 private bool $profile_incomplete = false;
79
81 private ProfileDataRepository $profile_data_repository;
82 private ProfileConfigurationRepository $profile_configuration_repository;
83
85 private DataFactory $data_factory;
87 private Services $irss;
90 private ilCtrl $ctrl;
91
92 public function __construct(
93 int $a_user_id = 0,
94 bool $a_call_by_reference = false
95 ) {
96 global $DIC;
97 $this->irss = $DIC['resource_storage'];
98 $this->settings = $DIC['ilSetting'];
99 $this->auth_session = $DIC['ilAuthSession'];
100 $this->ctrl = $DIC['ilCtrl'];
101 $this->app_event_handler = $DIC['ilAppEventHandler'];
102 $this->delivery = $DIC['file_delivery']->delivery();
103
104 if (defined('USER_FOLDER_ID')) {
105 $this->time_limit_owner = USER_FOLDER_ID;
106 }
107
108 $local_dic = LocalDIC::dic();
109 $this->profile_data_repository = $local_dic[ProfileDataRepository::class];
110 $this->profile_data = $this->profile_data_repository->getDefault();
111 $this->profile_configuration_repository = $local_dic[ProfileConfigurationRepository::class];
112
113 $this->data_factory = (new DataFactory());
114
115 $this->type = 'usr';
116 parent::__construct($a_user_id, $a_call_by_reference);
117
118 $this->cron_delete_user_reminder_mail = new ilCronDeleteInactiveUserReminderMail($this->db);
119
120 $this->auth_mode = 'default';
121 $this->passwd_type = self::PASSWD_PLAIN;
122 if ($a_user_id > 0) {
123 $this->setId($a_user_id);
124 $this->read();
125 return;
126 }
127
128 $this->prefs = [];
129 $this->prefs['language'] = $this->ilias->ini->readVariable('language', 'default');
130 $this->prefs['skin'] = $this->ilias->ini->readVariable('layout', 'skin');
131 $this->prefs['style'] = $this->ilias->ini->readVariable('layout', 'style');
132 }
133
139 public function read(): void
140 {
141 $this->profile_data = $this->profile_data_repository->getSingle($this->id);
142 $this->setFullname();
143 $this->assignSystemInformationFromDB($this->profile_data->getSystemInformation());
144
145 $this->readPrefs();
146
147 parent::read();
148 }
149
150 public function saveAsNew(): void
151 {
152 $this->inactivation_date = null;
153 if ($this->active === 0) {
154 $this->inactivation_date = date('Y-m-d H:i:s');
155 }
156
157 $system_information = $this->buildSystemInformationArrayForDB();
158 $system_information['create_date'] = $this->data_factory->clock()->utc()->now()
159 ->format(self::DATABASE_DATE_FORMAT);
160
161 $this->profile_data = $this->profile_data->withId($this->id);
162 $this->profile_data_repository->store(
163 $this->profile_data->withSystemInformation($this->buildSystemInformationArrayForDB())
164 );
165
166 // CREATE ENTRIES FOR MAIL BOX
167 $mbox = new ilMailbox($this->id);
168 $mbox->createDefaultFolder();
169
170 $mail_options = new ilMailOptions($this->id);
171 $mail_options->createMailOptionsEntry();
172
173 $this->app_event_handler->raise(
174 'components/ILIAS/User',
175 'afterCreate',
176 ['user_obj' => $this]
177 );
178 }
179
180 public function update(): bool
181 {
182 $this->profile_data_repository->store(
183 $this->profile_data->withSystemInformation($this->buildSystemInformationArrayForDB())
184 );
185
186 $this->writePrefs();
187
188 parent::update();
189 $this->updateOwner();
190
191 $this->read();
192
193 $this->app_event_handler->raise(
194 'components/ILIAS/User',
195 'afterUpdate',
196 ['user_obj' => $this]
197 );
198
199 return true;
200 }
201
202 private function assignSystemInformationFromDB(array $data): void
203 {
204 if (!empty($data['passwd'])) {
205 $this->setPasswd($data['passwd'], self::PASSWD_CRYPTED);
206 }
207
208 $this->password_salt = $data['passwd_salt'];
209 $this->password_encoding_type = $data['passwd_enc_type'];
210 $this->last_password_change_ts = $data['last_password_change'];
211 $this->login_attempts = $data['login_attempts'];
212 $this->passwd_policy_reset = $data['passwd_policy_reset'];
213 $this->client_ip = $data['client_ip'];
214 $this->last_login = $data['last_login'];
215 $this->first_login = $data['first_login'];
216 $this->last_profile_prompt = $data['last_profile_prompt'];
217 $this->last_update = $data['last_update'];
218 $this->create_date = $data['create_date'];
219 $this->approve_date = $data['approve_date'];
220 $this->active = $data['active'];
221 $this->agree_date = $data['agree_date'];
222 $this->inactivation_date = $data['inactivation_date'];
223
224 $this->time_limit_owner = $data['time_limit_owner'];
225 $this->time_limit_unlimited = $data['time_limit_unlimited'];
226 $this->time_limit_from = $data['time_limit_from'];
227 $this->time_limit_until = $data['time_limit_until'];
228
229 $this->profile_incomplete = $data['profile_incomplete'];
230
231 $this->auth_mode = $data['auth_mode'];
232 $this->ext_account = $data['ext_account'] ?? '';
233 $this->is_self_registered = $data['is_self_registered'];
234 }
235
236 private function buildSystemInformationArrayForDB(): array
237 {
238 return [
239 'last_password_change' => $this->last_password_change_ts,
240 'login_attempts' => $this->login_attempts,
241 'passwd' => $this->prepareAndRetrievePasswordForStorage(),
242 'passwd_salt' => $this->password_salt,
243 'passwd_enc_type' => $this->password_encoding_type,
244 'passwd_policy_reset' => $this->passwd_policy_reset,
245 'client_ip' => $this->client_ip,
246 'last_login' => $this->last_login,
247 'first_login' => $this->first_login,
248 'last_profile_prompt' => $this->last_profile_prompt,
249 'active' => $this->active,
250 'approve_date' => $this->approve_date,
251 'agree_date' => $this->retrieveAgreeDateForStorage(),
252 'inactivation_date' => $this->inactivation_date,
253 'time_limit_owner' => $this->time_limit_owner,
254 'time_limit_unlimited' => $this->time_limit_unlimited,
255 'time_limit_from' => $this->time_limit_from,
256 'time_limit_until' => $this->time_limit_until,
257 'profile_incomplete' => $this->profile_incomplete,
258 'auth_mode' => $this->auth_mode,
259 'ext_account' => $this->ext_account ?? '',
260 'is_self_registered' => $this->is_self_registered,
261 'last_update' => $this->last_update,
262 'create_date' => $this->create_date,
263 ];
264 }
265
266 private function prepareAndRetrievePasswordForStorage(): string
267 {
268 if ($this->passwd_type === self::PASSWD_PLAIN
269 && $this->passwd !== '') {
270 LocalUserPasswordManager::getInstance()->encodePassword($this, $this->passwd);
271 }
272
273 return $this->passwd;
274 }
275
276 private function retrieveAgreeDateForStorage(): ?string
277 {
278 if (is_string($this->agree_date && strtotime($this->agree_date) === false)) {
279 return null;
280 }
281 return $this->agree_date;
282 }
283
284 public function resetPassword(string $new_raw_password): bool
285 {
286 LocalUserPasswordManager::getInstance()->encodePassword($this, $new_raw_password);
287 $this->profile_data_repository->storePasswordFor(
288 $this->id,
289 $this->passwd,
290 $this->password_encoding_type,
291 $this->password_salt
292 );
293 return true;
294 }
295
296 public function getLastHistoryData(): ?array
297 {
298 $this->db->setLimit(1, 0);
299 $res = $this->db->queryF(
300 '
301 SELECT login, history_date FROM loginname_history
302 WHERE usr_id = %s ORDER BY history_date DESC',
303 ['integer'],
304 [$this->id]
305 );
306 $row = $this->db->fetchAssoc($res);
307 if ($row === null) {
308 return null;
309 }
310
311 return [
312 $row['login'],
313 $row['history_date']
314 ];
315 }
316
317 public function updateLogin(string $login): bool
318 {
319 if ($login === '' || $login === $this->profile_data->getAlias()) {
320 return false;
321 }
322
323 $last_history_entry = $this->getLastHistoryData();
324
325 if (!$this->profile_configuration_repository
326 ->getByClass(Alias::class)->isChangeableByUser()) {
327 throw new ilUserException($this->lng->txt('permission_denied'));
328 }
329
330 // throw exception if the desired loginame is already in history and it is not allowed to reuse it
331 if ($this->settings->get('reuse_of_loginnames') === '0'
332 && self::_doesLoginnameExistInHistory($login)) {
333 throw new ilUserException($this->lng->txt('loginname_already_exists'));
334 }
335
336 if ((int) $this->settings->get('loginname_change_blocking_time') > 0
337 && is_array($last_history_entry)
338 && $last_history_entry[1] + (int) $this->settings->get('loginname_change_blocking_time') > time()) {
339 throw new ilUserException(
340 sprintf(
341 $this->lng->txt('changing_loginname_not_possible_info'),
343 new ilDateTime($last_history_entry[1], IL_CAL_UNIX)
344 ),
346 new ilDateTime(($last_history_entry[1] + (int) $this->settings->get('loginname_change_blocking_time')), IL_CAL_UNIX)
347 )
348 )
349 );
350 }
351
352 if ($this->settings->get('create_history_loginname') === '1') {
353 $this->writeHistory($this->profile_data->getAlias());
354 }
355
356 $this->profile_data = $this->profile_data->withAlias($login);
357 $this->profile_data_repository->storeLoginFor($this->id, $this->profile_data->getAlias());
358
359 return true;
360 }
361
362 private function writeHistory(string $login): void
363 {
364 $res = $this->db->queryF(
365 'SELECT * FROM loginname_history WHERE usr_id = %s AND login = %s AND history_date = %s',
366 ['integer', 'text', 'integer'],
367 [$this->id, $login, time()]
368 );
369
370 if ($this->db->numRows($res) == 0) {
371 $this->db->manipulateF(
372 '
373 INSERT INTO loginname_history
374 (usr_id, login, history_date)
375 VALUES (%s, %s, %s)',
376 ['integer', 'text', 'integer'],
377 [$this->id, $login, time()]
378 );
379 }
380 }
381
382 public function writePref(
383 string $keyword,
384 string $value
385 ): void {
386 $this->db->replace(
387 'usr_pref',
388 [
389 'usr_id' => [ilDBConstants::T_INTEGER, $this->id],
390 'keyword' => [ilDBConstants::T_TEXT, $keyword],
391 ],
392 [
393 'value' => [ilDBConstants::T_TEXT,$value]
394 ]
395 );
396 $this->setPref($keyword, $value);
397 }
398
399 public function deletePref(string $keyword): void
400 {
401 $this->db->manipulateF(
402 'DELETE FROM usr_pref WHERE usr_id = %s AND keyword = %s',
403 ['integer', 'text'],
404 [$this->id, $keyword]
405 );
406 unset($this->prefs[$keyword]);
407 }
408
409 private function deleteAllPrefs(): void
410 {
411 $this->db->manipulateF(
412 'DELETE FROM usr_pref WHERE usr_id = %s',
413 ['integer'],
414 [$this->id]
415 );
416 }
417
418 public function writePrefs(): void
419 {
420 $this->deleteAllPrefs();
421 foreach ($this->prefs as $keyword => $value) {
422 $this->writePref($keyword, (string) $value);
423 }
424 }
425
426 public function getTimeZone(): string
427 {
428 $tz = $this->getPref('user_tz');
429 if ($tz !== null) {
430 return $tz;
431 }
432 return ilCalendarSettings::_getInstance()->getDefaultTimeZone();
433 }
434
435 public function getTimeFormat(): string
436 {
437 $format = $this->getPref('time_format');
438 if ($format !== null) {
439 return $format;
440 }
441 return ilCalendarSettings::_getInstance()->getDefaultTimeFormat();
442 }
443
444 public function getDateFormat(): DateFormat
445 {
446 $format = $this->getPref('date_format');
447 if ($format === null) {
448 $format = ilCalendarSettings::_getInstance()->getDefaultDateFormat();
449 }
450
451 return match ((int) $format) {
452 ilCalendarSettings::DATE_FORMAT_DMY => $this->data_factory->dateFormat()->germanShort(),
453 ilCalendarSettings::DATE_FORMAT_MDY => $this->data_factory->dateFormat()->americanShort(),
454 ilCalendarSettings::DATE_FORMAT_YMD => $this->data_factory->dateFormat()->standard(),
455 default => $this->data_factory->dateFormat()->standard()
456 };
457 }
458
459 public function getDateTimeFormat(): DateFormat
460 {
461 if ($this->getTimeFormat() === (string) \ilCalendarSettings::TIME_FORMAT_24) {
462 return $this->data_factory->dateFormat()->withTime24($this->getDateFormat());
463 }
464 return $this->data_factory->dateFormat()->withTime12($this->getDateFormat());
465 }
466
467 public function setPref(string $a_keyword, ?string $a_value): void
468 {
469 if ($a_keyword !== '') {
470 $this->prefs[$a_keyword] = $a_value;
471 }
472 }
473
474 public function getPref(string $a_keyword): ?string
475 {
476 return $this->prefs[$a_keyword] ?? null;
477 }
478
482 public function getPrefs(): array
483 {
484 return $this->prefs;
485 }
486
487 private function readPrefs(): void
488 {
489 $this->prefs = self::_getPreferences($this->id);
490 if (!isset($this->prefs['style'])
491 || $this->prefs['style'] === ''
492 || !ilStyleDefinition::styleExists($this->prefs['style'])
493 || !ilStyleDefinition::skinExists($this->prefs['skin'])
494 && ilStyleDefinition::styleExistsForSkinId($this->prefs['skin'], $this->prefs['style'])) {
495 $this->prefs['skin'] = $this->ilias->ini->readVariable('layout', 'skin');
496 $this->prefs['style'] = $this->ilias->ini->readVariable('layout', 'style');
497 }
498 }
499
500 public function delete(): bool
501 {
502 $this->app_event_handler->raise(
503 'Services/User',
504 'deleteUser',
505 ['usr_id' => $this->getId()]
506 );
507
509 ilLDAPRoleGroupMapping::_getInstance()->deleteUser($this->getId());
510 $this->rbac_admin->removeUser($this->getId());
511 (ilOrgUnitUserAssignmentQueries::getInstance())->deleteAllAssignmentsOfUser($this->getId());
512
513 $mailbox = new ilMailbox($this->getId());
514 $mailbox->delete();
515 $mailbox->updateMailsOfDeletedUser($this->getLogin());
516
525 (new ilWorkspaceTree($this->id))->cascadingDelete();
526 $this->cron_delete_user_reminder_mail->removeSingleUserFromTable($this->getId());
528 $this->clipboardDeleteAll();
529
530 $this->deleteAllPrefs();
531 $this->removeUserPicture();
532 $this->profile_data_repository->deleteForUser($this->getId());
533
534 $this->resetOwner();
535 parent::delete();
536
537 return true;
538 }
539
540 public function withProfileData(Data $profile_data): self
541 {
542 $clone = clone $this;
543 $clone->profile_data = $profile_data;
544 return $clone;
545 }
546
547 public function getProfileData(): Data
548 {
549 return $this->profile_data;
550 }
551
552 public function setLogin(string $login): void
553 {
554 $this->profile_data = $this->profile_data->withAlias($login);
555 }
556
557 public function getLogin(): string
558 {
559 return $this->profile_data->getAlias();
560 }
561
562 public function setGender(string $gender_string): void
563 {
564 $this->profile_data = $this->profile_data->withGender(Genders::tryFrom($gender_string));
565 }
566
567 public function getGender(): string
568 {
569 return $this->profile_data->getGender()?->value ?? '';
570 }
571
575 public function setUTitle(string $user_title): void
576 {
577 $this->setFullname();
578 $this->profile_data = $this->profile_data->withTitle($user_title);
579 }
580
581 public function getUTitle(): string
582 {
583 return $this->profile_data->getTitle();
584 }
585
586 public function setFirstname(string $firstname): void
587 {
588 $this->profile_data = $this->profile_data->withFirstname($firstname);
589 $this->setFullname();
590 }
591
592 public function getFirstname(): string
593 {
594 return $this->profile_data->getFirstname();
595 }
596
597 public function setLastname(string $lastname): void
598 {
599 $this->profile_data = $this->profile_data->withLastname($lastname);
600 $this->setFullname();
601 }
602
603 public function getLastname(): string
604 {
605 return $this->profile_data->getLastname();
606 }
607
608 public function setBirthday(?string $birthday): void
609 {
610 if ($birthday === null || $birthday === '') {
611 $this->profile_data = $this->profile_data->withBirthday(null);
612 return;
613 }
614
615 $this->profile_data = $this->profile_data->withBirthday(
616 new \DateTimeImmutable($birthday, new DateTimeZone('UTC'))
617 );
618 }
619
620 public function getBirthday(): ?string
621 {
622 return $this->profile_data->getBirthday()?->format('Y-m-d');
623 }
624
625 public function setInstitution(string $instituion): void
626 {
627 $this->profile_data = $this->profile_data->withInstitution($instituion);
628 }
629
630 public function getInstitution(): string
631 {
632 return $this->profile_data->getInstitution();
633 }
634
635 public function setDepartment(string $department): void
636 {
637 $this->profile_data = $this->profile_data->withDepartment($department);
638 }
639
640 public function getDepartment(): string
641 {
642 return $this->profile_data->getDepartment();
643 }
644
645 public function setStreet(string $street): void
646 {
647 $this->profile_data = $this->profile_data->withStreet($street);
648 }
649
650 public function getStreet(): string
651 {
652 return $this->profile_data->getStreet();
653 }
654
655 public function setCity(string $city): void
656 {
657 $this->profile_data = $this->profile_data->withCity($city);
658 }
659
660 public function getCity(): string
661 {
662 return $this->profile_data->getCity();
663 }
664
665 public function setZipcode(string $zipcode): void
666 {
667 $this->profile_data = $this->profile_data->withZipcode($zipcode);
668 }
669
670 public function getZipcode(): string
671 {
672 return $this->profile_data->getZipcode();
673 }
674
675 public function setCountry(string $country): void
676 {
677 $this->profile_data = $this->profile_data->withCountry($country);
678 }
679
680 public function getCountry(): string
681 {
682 return $this->profile_data->getCountry();
683 }
684
685 public function setPhoneOffice(string $phone): void
686 {
687 $this->profile_data = $this->profile_data->withPhoneOffice($phone);
688 }
689
690 public function getPhoneOffice(): string
691 {
692 return $this->profile_data->getPhoneOffice();
693 }
694
695 public function setPhoneHome(string $phone): void
696 {
697 $this->profile_data = $this->profile_data->withPhoneHome($phone);
698 }
699
700 public function getPhoneHome(): string
701 {
702 return $this->profile_data->getPhoneHome();
703 }
704
705 public function setPhoneMobile(string $phone): void
706 {
707 $this->profile_data = $this->profile_data->withPhoneMobile($phone);
708 }
709
710 public function getPhoneMobile(): string
711 {
712 return $this->profile_data->getPhoneMobile();
713 }
714
715 public function setFax(string $fax): void
716 {
717 $this->profile_data = $this->profile_data->withFax($fax);
718 }
719
720 public function getFax(): string
721 {
722 return $this->profile_data->getFax();
723 }
724
725 public function setMatriculation(string $matriculation): void
726 {
727 $this->profile_data = $this->profile_data->withMatriculation($matriculation);
728 }
729
730 public function getMatriculation(): string
731 {
732 return $this->profile_data->getMatriculation();
733 }
734
735 public function setEmail(string $email): void
736 {
737 $this->profile_data = $this->profile_data->withEmail($email);
738 }
739
740 public function getEmail(): string
741 {
742 return $this->profile_data->getEmail();
743 }
744
745 public function setSecondEmail(?string $email): void
746 {
747 $this->profile_data = $this->profile_data->withSecondEmail($email);
748 }
749
750 public function getSecondEmail(): ?string
751 {
752 return $this->profile_data->getSecondEmail();
753 }
754
755 public function setHobby(string $hobby): void
756 {
757 $this->profile_data = $this->profile_data->withHobby($hobby);
758 }
759
760 public function getHobby(): string
761 {
762 return $this->profile_data->getHobby();
763 }
764
765 public function setComment(string $referral_comment): void
766 {
767 $this->profile_data = $this->profile_data->withReferralComment($referral_comment);
768 }
769
770 public function getComment(): string
771 {
772 return $this->profile_data->getReferralComment();
773 }
774
775 public function setLatitude(?string $latitude): void
776 {
777 $coordinates = $this->profile_data->getGeoCoordinates();
778 $coordinates['latitude'] = $latitude;
779 $this->profile_data = $this->profile_data->withGeoCoordinates($coordinates);
780 }
781
782 public function getLatitude(): ?string
783 {
784 return $this->profile_data->getGeoCoordinates()['latitude'] ?? null;
785 }
786
787 public function setLongitude(?string $longitude): void
788 {
789 $coordinates = $this->profile_data->getGeoCoordinates();
790 $coordinates['longitude'] = $longitude;
791 $this->profile_data = $this->profile_data->withGeoCoordinates($coordinates);
792 }
793
794 public function getLongitude(): ?string
795 {
796 return $this->profile_data->getGeoCoordinates()['longitude'] ?? null;
797 }
798
799 public function setLocationZoom(?int $zoom): void
800 {
801 $coordinates = $this->profile_data->getGeoCoordinates();
802 $coordinates['zoom'] = $zoom;
803 $this->profile_data = $this->profile_data->withGeoCoordinates($coordinates);
804 }
805
806 public function getLocationZoom(): ?int
807 {
808 return $this->profile_data->getGeoCoordinates()['zoom'] ?? null;
809 }
810
812 {
813 return $this->profile_data->getAvatarRid();
814 }
815
816 public function setAvatarRid(?ResourceIdentification $avatar_rid): void
817 {
818 $this->profile_data = $this->profile_data->withAvatarRid($avatar_rid);
819 }
820
821 public function setClientIP(string $a_str): void
822 {
823 $this->client_ip = $a_str;
824 }
825
826 public function getClientIP(): string
827 {
828 return $this->client_ip;
829 }
830
831 public function setLanguage(string $language): void
832 {
833 $this->setPref('language', $language);
834 ilSession::clear('lang');
835 }
836
837 public function getLanguage(): string
838 {
839 return $this->prefs['language'] ?? '';
840 }
841
842 public function getPasswordEncodingType(): ?string
843 {
844 return $this->password_encoding_type;
845 }
846
847 public function setPasswordEncodingType(?string $password_encryption_type): void
848 {
849 $this->password_encoding_type = $password_encryption_type;
850 }
851
852 public function getPasswordSalt(): ?string
853 {
854 return $this->password_salt;
855 }
856
857 public function setPasswordSalt(?string $password_salt): void
858 {
859 $this->password_salt = $password_salt;
860 }
861
862 public function setFullname(): void
863 {
864 $title = $this->profile_data->getTitle() !== '' ? "{$this->profile_data->getTitle()} " : '';
865 $this->fullname = "{$title}{$this->profile_data->getFirstname()} {$this->profile_data->getLastname()}";
866 }
867
880 public function getFullname(int $max_strlen = 0): string
881 {
882 if ($max_strlen === 0) {
883 return ilUtil::stripSlashes($this->fullname);
884 }
885
886 if (mb_strlen($this->fullname) <= $max_strlen) {
887 return ilUtil::stripSlashes($this->fullname);
888 }
889
890 $length_lastname = mb_strlen($this->lastname);
891 if (mb_strlen($this->utitle) + $length_lastname + 4 <= $max_strlen) {
892 return ilUtil::stripSlashes($this->utitle . ' ' . substr($this->firstname, 0, 1) . '. ' . $this->lastname);
893 }
894
895 if (mb_strlen($this->firstname) + $length_lastname + 1 <= $max_strlen) {
896 return ilUtil::stripSlashes($this->firstname . ' ' . $this->lastname);
897 }
898
899 if ($length_lastname + 3 <= $max_strlen) {
900 return ilUtil::stripSlashes(substr($this->firstname, 0, 1) . '. ' . $this->lastname);
901 }
902
903 return ilUtil::stripSlashes(substr($this->lastname, 0, $max_strlen));
904 }
905
906 public function setPasswd(
907 string $a_str,
908 string $a_type = ilObjUser::PASSWD_PLAIN
909 ): void {
910 $this->passwd = $a_str;
911 $this->passwd_type = $a_type;
912 }
913
917 public function getPasswd(): string
918 {
919 return $this->passwd;
920 }
921
925 public function getPasswdType(): string
926 {
927 return $this->passwd_type;
928 }
929
930 public function setLastPasswordChangeTS(int $a_last_password_change_ts): void
931 {
932 $this->last_password_change_ts = $a_last_password_change_ts;
933 }
934
935 public function getLastPasswordChangeTS(): int
936 {
937 return $this->last_password_change_ts;
938 }
939
940 public function getPasswordPolicyResetStatus(): bool
941 {
942 return $this->passwd_policy_reset;
943 }
944
945 public function setPasswordPolicyResetStatus(bool $status): void
946 {
947 $this->passwd_policy_reset = $status;
948 }
949
953 public function getCurrentLanguage(): string
954 {
955 return ilSession::get('lang') ?? '';
956 }
957
961 public function setCurrentLanguage(string $language): void
962 {
963 ilSession::set('lang', $language);
964 }
965
966 public function setLastLogin(string $a_str): void
967 {
968 $this->last_login = $a_str;
969 }
970
971 public function getLastLogin(): string
972 {
973 return $this->last_login;
974 }
975
976 public function refreshLogin(): void
977 {
978 $this->last_login = $this->db->now();
979
980 $old_first_login = $this->first_login;
981 if ($old_first_login === '') {
982 $this->first_login = $this->db->now();
983 $this->app_event_handler->raise(
984 'components/ILIAS/User',
985 'firstLogin',
986 ['user_obj' => $this]
987 );
988 }
989 }
990
991 public function setFirstLogin(string $date): void
992 {
993 $this->first_login = $date;
994 }
995
996 public function getFirstLogin(): string
997 {
998 return $this->first_login;
999 }
1000
1001 public function setLastProfilePrompt(string $date): void
1002 {
1003 $this->last_profile_prompt = $date;
1004 }
1005
1006 public function getLastProfilePrompt(): string
1007 {
1008 return $this->last_profile_prompt;
1009 }
1010
1011 public function setLastUpdate(string $date): void
1012 {
1013 $this->last_update = $date;
1014 }
1015
1016 public function getLastUpdate(): string
1017 {
1018 return $this->last_update;
1019 }
1020
1025 public function setApproveDate(?string $a_str): void
1026 {
1027 $this->approve_date = $a_str;
1028 }
1029
1030 public function getApproveDate(): ?string
1031 {
1032 return $this->approve_date;
1033 }
1034
1035 public function getAgreeDate(): ?string
1036 {
1037 return $this->agree_date;
1038 }
1039 public function setAgreeDate(?string $date): void
1040 {
1041 $this->agree_date = $date;
1042 }
1043
1048 public function setActive(
1049 bool $active,
1050 int $owner = 0
1051 ): void {
1052 $this->setOwner($owner);
1053
1054 $current_active = $this->active;
1055 if ($active) {
1056 $this->active = 1;
1057 $this->setApproveDate(date('Y-m-d H:i:s'));
1058 $this->setInactivationDate(null);
1059 $this->setOwner($owner);
1060 return;
1061 }
1062
1063 $this->active = 0;
1064 $this->setApproveDate(null);
1065
1066 if ($this->getId() > 0 && $current_active !== $active) {
1067 $this->setInactivationDate(ilUtil::now());
1068 }
1069 }
1070
1071 public function getActive(): bool
1072 {
1073 return $this->active === 1;
1074 }
1075
1076 public function getSkin(): string
1077 {
1078 return $this->prefs['skin'];
1079 }
1080
1081 public function setTimeLimitOwner(int $a_owner): void
1082 {
1083 $this->time_limit_owner = $a_owner;
1084 }
1085
1086 public function getTimeLimitOwner(): int
1087 {
1088 return $this->time_limit_owner;
1089 }
1090
1091 public function setTimeLimitFrom(?int $a_from): void
1092 {
1093 $this->time_limit_from = $a_from;
1094 }
1095
1096 public function getTimeLimitFrom(): ?int
1097 {
1098 return $this->time_limit_from;
1099 }
1100
1101 public function setTimeLimitUntil(?int $a_until): void
1102 {
1103 $this->time_limit_until = $a_until;
1104 }
1105
1106 public function getTimeLimitUntil(): ?int
1107 {
1108 return $this->time_limit_until;
1109 }
1110
1111 public function setTimeLimitUnlimited(bool $unlimited): void
1112 {
1113 $this->time_limit_unlimited = $unlimited;
1114 }
1115
1116 public function getTimeLimitUnlimited(): bool
1117 {
1118 return $this->time_limit_unlimited;
1119 }
1120
1121 public function setLoginAttempts(int $a_login_attempts): void
1122 {
1123 $this->login_attempts = $a_login_attempts;
1124 }
1125
1126 public function getLoginAttempts(): int
1127 {
1128 return $this->login_attempts;
1129 }
1130
1131 public function checkTimeLimit(): bool
1132 {
1133 if ($this->getTimeLimitUnlimited()) {
1134 return true;
1135 }
1136 if ($this->getTimeLimitFrom() < time() and $this->getTimeLimitUntil() > time()) {
1137 return true;
1138 }
1139 return false;
1140 }
1141
1142 public function setProfileIncomplete(bool $a_prof_inc): void
1143 {
1144 $this->profile_incomplete = $a_prof_inc;
1145 }
1146
1147 public function getProfileIncomplete(): bool
1148 {
1149 if ($this->id == ANONYMOUS_USER_ID) {
1150 return false;
1151 }
1152 return $this->profile_incomplete;
1153 }
1154
1155 public function isPasswordChangeDemanded(): bool
1156 {
1157 if ($this->id === ANONYMOUS_USER_ID) {
1158 return false;
1159 }
1160
1161 if ($this->id === SYSTEM_USER_ID) {
1162 if (LocalUserPasswordManager::getInstance()->verifyPassword($this, base64_decode('aG9tZXI='))
1163 && !ilAuthUtils::_needsExternalAccountByAuthMode($this->getAuthMode(true))
1164 ) {
1165 return true;
1166 }
1167 return false;
1168 }
1169
1170 return !ilAuthUtils::_needsExternalAccountByAuthMode($this->getAuthMode(true))
1171 && ($this->getPasswordPolicyResetStatus()
1172 || ilSecuritySettings::_getInstance()->isPasswordChangeOnFirstLoginEnabled()
1173 && $this->getLastPasswordChangeTS() === 0
1174 && $this->is_self_registered === false);
1175 }
1176
1177 public function isPasswordExpired(): bool
1178 {
1179 if ($this->id === ANONYMOUS_USER_ID
1180 || $this->getLastPasswordChangeTS() === 0) {
1181 return false;
1182 }
1183
1184 $max_pass_age_in_seconds = ilSecuritySettings::_getInstance()->getPasswordMaxAge() * 86400;
1185 if ($max_pass_age_in_seconds === 0) {
1186 return false;
1187 }
1188
1189 if (time() - $this->getLastPasswordChangeTS() > $max_pass_age_in_seconds
1190 && !ilAuthUtils::_needsExternalAccountByAuthMode($this->getAuthMode(true))) {
1191 return true;
1192 }
1193
1194 return false;
1195 }
1196
1197 public function getPasswordAge(): int
1198 {
1199 return (int) (time() - $this->getLastPasswordChangeTS() / 86400);
1200 }
1201
1202 public function setLastPasswordChangeToNow(): void
1203 {
1204 $this->last_password_change_ts = time();
1205 }
1206
1207 public function resetLastPasswordChange(): void
1208 {
1209 $this->last_password_change_ts = 0;
1210 }
1211
1212 public function setAuthMode(?string $a_str): void
1213 {
1214 $this->auth_mode = $a_str;
1215 }
1216
1217 public function getAuthMode(bool $a_auth_key = false): ?string
1218 {
1219 if (!$a_auth_key) {
1220 return $this->auth_mode;
1221 }
1222 return ilAuthUtils::_getAuthMode($this->auth_mode);
1223 }
1224
1225 public function setExternalAccount(string $a_str): void
1226 {
1227 $this->ext_account = $a_str;
1228 }
1229
1230 public function getExternalAccount(): string
1231 {
1232 return $this->ext_account;
1233 }
1234
1241 public function addObjectToClipboard(
1242 int $a_item_id,
1243 string $a_type,
1244 string $a_title,
1245 int $a_parent = 0,
1246 string $a_time = '',
1247 int $a_order_nr = 0
1248 ): void {
1249 global $DIC;
1250
1251 $ilDB = $DIC['ilDB'];
1252
1253 if ($a_time === '') {
1254 $a_time = date('Y-m-d H:i:s');
1255 }
1256
1257 $item_set = $ilDB->queryF(
1258 'SELECT * FROM personal_clipboard WHERE ' .
1259 'parent = %s AND item_id = %s AND type = %s AND user_id = %s',
1260 ['integer', 'integer', 'text', 'integer'],
1261 [0, $a_item_id, $a_type, $this->getId()]
1262 );
1263
1264 // only insert if item is not already in clipboard
1265 if (!$item_set->fetchRow()) {
1266 $ilDB->manipulateF(
1267 'INSERT INTO personal_clipboard ' .
1268 '(item_id, type, user_id, title, parent, insert_time, order_nr) VALUES ' .
1269 ' (%s,%s,%s,%s,%s,%s,%s)',
1270 ['integer', 'text', 'integer', 'text', 'integer', 'timestamp', 'integer'],
1271 [$a_item_id, $a_type, $this->getId(), $a_title, $a_parent, $a_time, $a_order_nr]
1272 );
1273 } else {
1274 $ilDB->manipulateF(
1275 'UPDATE personal_clipboard SET insert_time = %s ' .
1276 'WHERE user_id = %s AND item_id = %s AND type = %s AND parent = 0',
1277 ['timestamp', 'integer', 'integer', 'text'],
1278 [$a_time, $this->getId(), $a_item_id, $a_type]
1279 );
1280 }
1281 }
1282
1287 public function addToPCClipboard(
1288 string $a_content,
1289 string $a_time,
1290 int $a_nr
1291 ): void {
1292 $ilDB = $this->db;
1293 if ($a_time == 0) {
1294 $a_time = date('Y-m-d H:i:s');
1295 }
1296 ilSession::set('user_pc_clip', true);
1297 $ilDB->insert('personal_pc_clipboard', [
1298 'user_id' => ['integer', $this->getId()],
1299 'content' => ['clob', $a_content],
1300 'insert_time' => ['timestamp', $a_time],
1301 'order_nr' => ['integer', $a_nr]
1302 ]);
1303 }
1304
1309 public function getPCClipboardContent(): array // Missing array type.
1310 {
1311 $ilDB = $this->db;
1312
1313 if (!ilSession::get('user_pc_clip')) {
1314 return [];
1315 }
1316
1317 $set = $ilDB->queryF('SELECT MAX(insert_time) mtime FROM personal_pc_clipboard ' .
1318 ' WHERE user_id = %s', ['integer'], [$this->getId()]);
1319 $row = $ilDB->fetchAssoc($set);
1320
1321 $set = $ilDB->queryF(
1322 'SELECT * FROM personal_pc_clipboard ' .
1323 ' WHERE user_id = %s AND insert_time = %s ORDER BY order_nr ASC',
1324 ['integer', 'timestamp'],
1325 [$this->getId(), $row['mtime']]
1326 );
1327 $content = [];
1328 while ($row = $ilDB->fetchAssoc($set)) {
1329 $content[] = $row['content'];
1330 }
1331
1332 return $content;
1333 }
1334
1338 public function clipboardHasObjectsOfType(string $a_type): bool
1339 {
1340 global $DIC;
1341
1342 $ilDB = $DIC['ilDB'];
1343
1344 $set = $ilDB->queryF(
1345 'SELECT * FROM personal_clipboard WHERE ' .
1346 'parent = %s AND type = %s AND user_id = %s',
1347 ['integer', 'text', 'integer'],
1348 [0, $a_type, $this->getId()]
1349 );
1350 if ($ilDB->fetchAssoc($set)) {
1351 return true;
1352 }
1353
1354 return false;
1355 }
1356
1357 public function clipboardDeleteObjectsOfType(string $a_type): void
1358 {
1359 $ilDB = $this->db;
1360
1361 $ilDB->manipulateF(
1362 'DELETE FROM personal_clipboard WHERE ' .
1363 'type = %s AND user_id = %s',
1364 ['text', 'integer'],
1365 [$a_type, $this->getId()]
1366 );
1367 }
1368
1369 public function clipboardDeleteAll(): void
1370 {
1371 global $DIC;
1372
1373 $ilDB = $DIC['ilDB'];
1374
1375 $ilDB->manipulateF('DELETE FROM personal_clipboard WHERE ' .
1376 'user_id = %s', ['integer'], [$this->getId()]);
1377 }
1378
1382 public function getClipboardObjects(
1383 string $a_type = '',
1384 bool $a_top_nodes_only = false
1385 ): array {
1386 global $DIC;
1387
1388 $ilDB = $DIC['ilDB'];
1389
1390 $par = '';
1391 if ($a_top_nodes_only) {
1392 $par = ' AND parent = ' . $ilDB->quote(0, 'integer') . ' ';
1393 }
1394
1395 $type_str = ($a_type != '')
1396 ? ' AND type = ' . $ilDB->quote($a_type, 'text') . ' '
1397 : '';
1398 $q = 'SELECT * FROM personal_clipboard WHERE ' .
1399 'user_id = ' . $ilDB->quote($this->getId(), 'integer') . ' ' .
1400 $type_str . $par .
1401 ' ORDER BY order_nr';
1402 $objs = $ilDB->query($q);
1403 $objects = [];
1404 while ($obj = $ilDB->fetchAssoc($objs)) {
1405 if ($obj['type'] == 'mob') {
1406 $obj['title'] = ilObject::_lookupTitle($obj['item_id']);
1407 if (ilObject::_lookupType((int) $obj['item_id']) !== 'mob') {
1408 continue;
1409 }
1410 }
1411 if ($obj['type'] == 'incl') {
1412 $obj['title'] = ilMediaPoolPage::lookupTitle($obj['item_id']);
1413 if (!ilPageObject::_exists('mep', (int) $obj['item_id'], '-')) {
1414 continue;
1415 }
1416 }
1417 $objects[] = ['id' => $obj['item_id'],
1418 'type' => $obj['type'], 'title' => $obj['title'],
1419 'insert_time' => $obj['insert_time']];
1420 }
1421 return $objects;
1422 }
1423
1427 public function getClipboardChilds(
1428 int $a_parent,
1429 string $a_insert_time
1430 ): array {
1431 global $DIC;
1432
1433 $ilDB = $DIC['ilDB'];
1434 $ilUser = $DIC['ilUser'];
1435
1436 $objs = $ilDB->queryF(
1437 'SELECT * FROM personal_clipboard WHERE ' .
1438 'user_id = %s AND parent = %s AND insert_time = %s ' .
1439 ' ORDER BY order_nr',
1440 ['integer', 'integer', 'timestamp'],
1441 [$ilUser->getId(), $a_parent, $a_insert_time]
1442 );
1443 $objects = [];
1444 while ($obj = $ilDB->fetchAssoc($objs)) {
1445 if ($obj['type'] == 'mob') {
1446 $obj['title'] = ilObject::_lookupTitle($obj['item_id']);
1447 }
1448 $objects[] = ['id' => $obj['item_id'],
1449 'type' => $obj['type'], 'title' => $obj['title'], 'insert_time' => $obj['insert_time']];
1450 }
1451 return $objects;
1452 }
1453
1455 int $a_item_id,
1456 string $a_type
1457 ): void {
1458 $ilDB = $this->db;
1459
1460 $q = 'DELETE FROM personal_clipboard WHERE ' .
1461 'item_id = ' . $ilDB->quote($a_item_id, 'integer') .
1462 ' AND type = ' . $ilDB->quote($a_type, 'text') . ' ' .
1463 ' AND user_id = ' . $ilDB->quote($this->getId(), 'integer');
1464 $ilDB->manipulate($q);
1465 }
1466
1467 public function getOrgUnitsRepresentation(): string
1468 {
1469 return self::lookupOrgUnitsRepresentation($this->getId());
1470 }
1471
1476 public function getPersonalPicturePath(
1477 string $a_size = 'small',
1478 bool $a_force_pic = false
1479 ): string {
1480 if (isset(self::$personal_image_cache[$this->getId()][$a_size][(int) $a_force_pic])) {
1481 return self::$personal_image_cache[$this->getId()][$a_size][(int) $a_force_pic];
1482 }
1483
1484 self::$personal_image_cache[$this->getId()][$a_size][(int) $a_force_pic] = self::_getPersonalPicturePath($this->getId(), $a_size, $a_force_pic);
1485
1486 return self::$personal_image_cache[$this->getId()][$a_size][(int) $a_force_pic];
1487 }
1488
1489 public function hasProfilePicture(): bool
1490 {
1491 return (new ilUserAvatarResolver($this->getId()))->hasProfilePicture();
1492 }
1493
1494 public function getAvatar(): Avatar
1495 {
1496 return self::_getAvatar($this->getId());
1497 }
1498
1499 public function removeUserPicture(): void
1500 {
1501 if ($this->getAvatarRid() !== null) {
1502 $this->irss->manage()->remove($this->getAvatarRid(), new ilUserProfilePictureStakeholder());
1503 }
1504
1505 $this->profile_data = $this->profile_data->withAvatarRid(null);
1506 $this->update();
1507 }
1508
1513 public function getProfileAsString(Language $language): string
1514 {
1515 global $DIC;
1516 $rbacreview = $DIC['rbacreview'];
1517 $profile = $DIC['user']->getProfile();
1518
1519 $language->loadLanguageModule('registration');
1520 $language->loadLanguageModule('crs');
1521
1522 $body = "{$language->txt('login')}: {$this->getLogin()}\n";
1523
1524 if ($this->profile_data->getTitle() !== '') {
1525 $body .= "{$language->txt('title')}: {$this->profile_data->getTitle()}\n";
1526 }
1527 if ($this->getGender() !== '') {
1528 $body .= ($language->txt('gender') . ': ' . $language->txt('gender_' . strtolower($this->getGender())) . "\n");
1529 }
1530 if ($this->getFirstname() !== '') {
1531 $body .= ($language->txt('firstname') . ': ' . $this->getFirstname() . "\n");
1532 }
1533 if ($this->getLastname() !== '') {
1534 $body .= ($language->txt('lastname') . ': ' . $this->getLastname() . "\n");
1535 }
1536 if ($this->getInstitution() !== '') {
1537 $body .= ($language->txt('institution') . ': ' . $this->getInstitution() . "\n");
1538 }
1539 if ($this->getDepartment() !== '') {
1540 $body .= ($language->txt('department') . ': ' . $this->getDepartment() . "\n");
1541 }
1542 if ($this->getStreet() !== '') {
1543 $body .= ($language->txt('street') . ': ' . $this->getStreet() . "\n");
1544 }
1545 if ($this->getCity() !== '') {
1546 $body .= ($language->txt('city') . ': ' . $this->getCity() . "\n");
1547 }
1548 if ($this->getZipcode() !== '') {
1549 $body .= ($language->txt('zipcode') . ': ' . $this->getZipcode() . "\n");
1550 }
1551 if ($this->getCountry() !== '') {
1552 $body .= ($language->txt('country') . ': ' . $this->getCountry() . "\n");
1553 }
1554 if ($this->getPhoneOffice() !== '') {
1555 $body .= ($language->txt('phone_office') . ': ' . $this->getPhoneOffice() . "\n");
1556 }
1557 if ($this->getPhoneHome() !== '') {
1558 $body .= ($language->txt('phone_home') . ': ' . $this->getPhoneHome() . "\n");
1559 }
1560 if ($this->getPhoneMobile() !== '') {
1561 $body .= ($language->txt('phone_mobile') . ': ' . $this->getPhoneMobile() . "\n");
1562 }
1563 if ($this->getFax() !== '') {
1564 $body .= ($language->txt('fax') . ': ' . $this->getFax() . "\n");
1565 }
1566 if ($this->getEmail() !== '') {
1567 $body .= ($language->txt('email') . ': ' . $this->getEmail() . "\n");
1568 }
1569 if ($this->getSecondEmail() !== null
1570 && $this->getSecondEmail() !== '') {
1571 $body .= ($language->txt('second_email') . ': ' . $this->getSecondEmail() . "\n");
1572 }
1573 if ($this->getHobby() !== '') {
1574 $body .= ($language->txt('hobby') . ': ' . $this->getHobby() . "\n");
1575 }
1576 if ($this->getComment() !== '') {
1577 $body .= ($language->txt('referral_comment') . ': ' . $this->getComment() . "\n");
1578 }
1579 if ($this->getMatriculation() !== '') {
1580 $body .= ($language->txt('matriculation') . ': ' . $this->getMatriculation() . "\n");
1581 }
1582 if ($this->getCreateDate() !== '') {
1585 $date = ilDatePresentation::formatDate(new ilDateTime($this->getCreateDate(), IL_CAL_DATETIME));
1587
1588 $body .= ($language->txt('create_date') . ': ' . $date . "\n");
1589 }
1590
1591 $gr = [];
1592 foreach ($rbacreview->getGlobalRoles() as $role) {
1593 if ($rbacreview->isAssigned($this->getId(), $role)) {
1594 $gr[] = ilObjRole::_lookupTitle($role);
1595 }
1596 }
1597 if (count($gr)) {
1598 $body .= ($language->txt('reg_role_info') . ': ' . implode(',', $gr) . "\n");
1599 }
1600
1601 // Time limit
1602 if ($this->getTimeLimitUnlimited()) {
1603 $body .= ($language->txt('time_limit') . ': ' . $language->txt('crs_unlimited') . "\n");
1604 } else {
1608 new ilDateTime($this->getTimeLimitFrom(), IL_CAL_UNIX),
1609 new ilDateTime($this->getTimeLimitUntil(), IL_CAL_UNIX)
1610 );
1612
1613 $start = new ilDateTime($this->getTimeLimitFrom(), IL_CAL_UNIX);
1614 $end = new ilDateTime($this->getTimeLimitUntil(), IL_CAL_UNIX);
1615
1616 $body .= $language->txt('time_limit') . ': ' .
1617 $language->txt('from') . ' ' .
1618 $start->get(IL_CAL_DATETIME) . ' ';
1619 $body .= $language->txt('to') . ' ' . $end->get(IL_CAL_DATETIME) . "\n";
1620 }
1621
1622 foreach ($profile->getAllUserDefinedFields() as $field) {
1623 $data = $field->retrieveValueFromUser($this);
1624 if ($data !== '') {
1625 $body .= "{$field->getLabel($this->lng)}: {$data}\n";
1626 }
1627 }
1628
1629 return $body;
1630 }
1631
1632 public function setFeedPass(
1633 string $a_password
1634 ): void {
1635 $this->writePref(
1636 'priv_feed_pass',
1637 ($a_password == '') ? '' : md5($a_password)
1638 );
1639 }
1640
1641 public function hasPublicProfile(): bool
1642 {
1643 return in_array($this->getPref('public_profile'), ['y', 'g']);
1644 }
1645
1646 public function getPublicName(): string
1647 {
1648 if ($this->hasPublicProfile()) {
1649 return $this->getFirstname() . ' ' . $this->getLastname() . ' (' . $this->getLogin() . ')';
1650 }
1651
1652 return $this->getLogin();
1653 }
1654
1655 public function resetOwner(): void
1656 {
1657 $ilDB = $this->db;
1658
1659 $query = 'UPDATE object_data SET owner = 0 ' .
1660 'WHERE owner = ' . $ilDB->quote($this->getId(), 'integer');
1661 $ilDB->query($query);
1662 }
1663
1664
1665 public function exportPersonalData(): void
1666 {
1667 if (!isset($this->user)) {
1668 global $DIC;
1669 $this->user = $DIC->user();
1670 }
1671 $export_consumer = (new ExportFactory())->consumer()->handler();
1672 $configs = $export_consumer->exportConfig()->allExportConfigs();
1674 $config = $configs->getElementByClassName('ilUserExportConfig');
1675 $config->setExportType('personal_data');
1676 $export = $export_consumer->createStandardExportByObject(
1677 $this->user->getId(),
1678 $this,
1679 $configs
1680 );
1681 $stream = Streams::ofString($export->getIRSSInfo()->getStream()->getContents());
1682 $file_name = $export->getIRSSInfo()->getFileName();
1683 $export->getIRSS()->delete($export_consumer->exportStakeholderHandler());
1684 $this->delivery->deliver($stream, $file_name);
1685 }
1686
1687 public function getPersonalDataExportFile(): string
1688 {
1689 $dir = ilExport::_getExportDirectory($this->getId(), 'xml', 'usr', 'personal_data');
1690 if (!is_dir($dir)) {
1691 return '';
1692 }
1693 foreach (ilFileUtils::getDir($dir) as $entry) {
1694 if (is_int(strpos($entry['entry'], '.zip'))) {
1695 return $entry['entry'];
1696 }
1697 }
1698
1699 return '';
1700 }
1701
1702 public function sendPersonalDataFile(): void
1703 {
1704 $file = ilExport::_getExportDirectory($this->getId(), 'xml', 'usr', 'personal_data') .
1705 '/' . $this->getPersonalDataExportFile();
1706 if (is_file($file)) {
1707 ilFileDelivery::deliverFileLegacy($file, $this->getPersonalDataExportFile());
1708 }
1709 }
1710
1711 public function importPersonalData(
1712 array $a_file,
1713 bool $a_profile_data,
1714 bool $a_settings,
1715 bool $a_notes,
1716 bool $a_calendar
1717 ): void {
1718 $imp = new ilImport();
1719 // bookmarks need to be skipped, importer does not exist anymore
1720 $imp->addSkipImporter('components/ILIAS/Bookmarks');
1721 if (!$a_profile_data) {
1722 $imp->addSkipEntity('components/ILIAS/User', 'usr_profile');
1723 }
1724 if (!$a_settings) {
1725 $imp->addSkipEntity('components/ILIAS/User', 'usr_setting');
1726 }
1727 if (!$a_notes) {
1728 $imp->addSkipEntity('components/ILIAS/Notes', 'user_notes');
1729 }
1730 if (!$a_calendar) {
1731 $imp->addSkipEntity('components/ILIAS/Calendar', 'calendar');
1732 }
1733 $imp->importEntity(
1734 $a_file['tmp_name'],
1735 $a_file['name'],
1736 'usr',
1737 'components/ILIAS/User'
1738 );
1739 }
1740
1741 public function setInactivationDate(?string $inactivation_date): void
1742 {
1743 $this->inactivation_date = $inactivation_date;
1744 }
1745
1746 public function getInactivationDate(): ?string
1747 {
1748 return $this->inactivation_date;
1749 }
1750
1751 public function isAnonymous(): bool
1752 {
1753 return self::_isAnonymous($this->getId());
1754 }
1755
1756 public static function _isAnonymous(int $usr_id): bool
1757 {
1758 return $usr_id == ANONYMOUS_USER_ID;
1759 }
1760
1761 public function activateDeletionFlag(): void
1762 {
1763 $this->writePref('delete_flag', true);
1764 }
1765
1766 public function removeDeletionFlag(): void
1767 {
1768 $this->writePref('delete_flag', false);
1769 }
1770
1771 public function hasDeletionFlag(): bool
1772 {
1773 return (bool) $this->getPref('delete_flag');
1774 }
1775
1776 public function setIsSelfRegistered(bool $status): void
1777 {
1778 $this->is_self_registered = $status;
1779 }
1780
1781 public function isSelfRegistered(): bool
1782 {
1783 return $this->is_self_registered;
1784 }
1785
1789 public function setGeneralInterests(?array $value = null): void
1790 {
1791 $this->profile_data = $this->profile_data->withAdditionalFieldByIdentifier(
1792 $this->profile_configuration_repository->getByClass(Interests::class)->getIdentifier(),
1793 $value ?? []
1794 );
1795 }
1796
1800 public function getGeneralInterests(): array
1801 {
1802 return $this->profile_data->getAdditionalFieldByIdentifier(
1803 $this->profile_configuration_repository->getByClass(Interests::class)->getIdentifier()
1804 ) ?? [];
1805 }
1806
1810 public function getGeneralInterestsAsText(): string
1811 {
1812 return $this->buildTextFromArray($this->getGeneralInterests());
1813 }
1814
1818 public function setOfferingHelp(?array $value = null): void
1819 {
1820 $this->profile_data = $this->profile_data->withAdditionalFieldByIdentifier(
1821 $this->profile_configuration_repository->getByClass(HelpOffered::class)->getIdentifier(),
1822 $value ?? []
1823 );
1824 }
1825
1829 public function getOfferingHelp(): array
1830 {
1831 return $this->profile_data->getAdditionalFieldByIdentifier(
1832 $this->profile_configuration_repository->getByClass(HelpOffered::class)->getIdentifier()
1833 ) ?? [];
1834 }
1835
1839 public function getOfferingHelpAsText(): string
1840 {
1841 return $this->buildTextFromArray($this->getOfferingHelp());
1842 }
1843
1844 public function setLookingForHelp(?array $value = null): void
1845 {
1846 $this->profile_data = $this->profile_data->withAdditionalFieldByIdentifier(
1847 $this->profile_configuration_repository->getByClass(HelpLookedFor::class)->getIdentifier(),
1848 $value ?? []
1849 );
1850 }
1851
1852 public function getLookingForHelp(): array
1853 {
1854 return $this->profile_data->getAdditionalFieldByIdentifier(
1855 $this->profile_configuration_repository->getByClass(HelpLookedFor::class)->getIdentifier()
1856 ) ?? [];
1857 }
1858
1859 public function getLookingForHelpAsText(): string
1860 {
1861 return $this->buildTextFromArray($this->getLookingForHelp());
1862 }
1863
1864
1865 public function uploadPersonalPicture(
1866 string $tmp_file
1867 ): bool {
1868 $stakeholder = new ilUserProfilePictureStakeholder();
1869 $stakeholder->setOwner($this->getId());
1870 $stream = Streams::ofResource(fopen($tmp_file, 'rb'));
1871
1872 if ($this->getAvatarRid() !== null && $this->getAvatarRid() !== ilObjUser::NO_AVATAR_RID) {
1873 $rid = $this->irss->manage()->find($this->getAvatarRid());
1874 // append profile picture
1875 $this->irss->manage()->replaceWithStream(
1876 $rid,
1877 $stream,
1878 $stakeholder
1879 );
1880 } else {
1881 // new profile picture
1882 $rid = $this->irss->manage()->stream(
1883 $stream,
1884 $stakeholder
1885 );
1886 }
1887
1888 $this->setAvatarRid($rid);
1889 $this->update();
1890 return true;
1891 }
1892
1893 public function generateRegistrationHash(): string
1894 {
1895 do {
1896 $hashcode = substr(md5(uniqid(mt_rand(), true)), 0, 16);
1897
1898 $res = $this->db->queryf(
1899 'SELECT COUNT(usr_id) cnt FROM usr_data WHERE reg_hash = %s',
1901 [$hashcode]
1902 );
1903 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1904 if ($row->cnt > 0) {
1905 continue 2;
1906 }
1907 break;
1908 }
1909
1910 $this->db->manipulateF(
1911 'UPDATE usr_data SET reg_hash = %s WHERE usr_id = %s',
1913 [$hashcode, $this->id]
1914 );
1915 break;
1916 } while (true);
1917
1918 return $hashcode;
1919 }
1920
1921
1922 private function buildTextFromArray(array $a_attr): string
1923 {
1924 if (count($a_attr) > 0) {
1925 return implode(', ', $a_attr);
1926 }
1927 return '';
1928 }
1929
1930 /*
1931 * 2025-07-16, sw: Hic sunt dracones. Static methods that need to be gone!
1932 */
1933
1934 public static function _loginExists(
1935 string $a_login,
1936 int $a_user_id = 0
1937 ): ?int {
1938 global $DIC;
1939 $ilDB = $DIC['ilDB'];
1940
1941 $q = 'SELECT DISTINCT login, usr_id FROM usr_data ' .
1942 'WHERE login = %s';
1943 $types[] = 'text';
1944 $values[] = $a_login;
1945
1946 if ($a_user_id != 0) {
1947 $q .= ' AND usr_id != %s ';
1948 $types[] = 'integer';
1949 $values[] = $a_user_id;
1950 }
1951
1952 $r = $ilDB->queryF($q, $types, $values);
1953
1954 if (($row = $ilDB->fetchAssoc($r))) {
1955 return (int) $row['usr_id'];
1956 }
1957 return null;
1958 }
1959
1960 public static function _externalAccountExists(
1961 string $a_external_account,
1962 string $a_auth_mode
1963 ): bool {
1964 global $DIC;
1965 $ilDB = $DIC['ilDB'];
1966
1967 $res = $ilDB->queryF(
1968 'SELECT * FROM usr_data ' .
1969 'WHERE ext_account = %s AND auth_mode = %s',
1970 ['text', 'text'],
1971 [$a_external_account, $a_auth_mode]
1972 );
1973 return (bool) $ilDB->fetchAssoc($res);
1974 }
1975
1976 public static function _getUsersForRole(
1977 int $role_id,
1978 int $active = -1
1979 ): array {
1980 global $DIC;
1981 $ilDB = $DIC['ilDB'];
1982 $rbacreview = $DIC['rbacreview'];
1983
1984 $ids = $rbacreview->assignedUsers($role_id);
1985
1986 if (count($ids) == 0) {
1987 $ids = [-1];
1988 }
1989
1990 $query = 'SELECT usr_data.*, usr_pref.value AS language
1991 FROM usr_data
1992 LEFT JOIN usr_pref ON usr_pref.usr_id = usr_data.usr_id AND usr_pref.keyword = %s
1993 WHERE ' . $ilDB->in('usr_data.usr_id', $ids, false, 'integer');
1994 $values[] = 'language';
1995 $types[] = 'text';
1996
1997
1998 if (is_numeric($active) && $active > -1) {
1999 $query .= ' AND usr_data.active = %s';
2000 $values[] = $active;
2001 $types[] = 'integer';
2002 }
2003
2004 $query .= ' ORDER BY usr_data.lastname, usr_data.firstname ';
2005
2006 $r = $ilDB->queryF($query, $types, $values);
2007 $data = [];
2008 while ($row = $ilDB->fetchAssoc($r)) {
2009 $data[] = $row;
2010 }
2011 return $data;
2012 }
2013
2014 public static function _getUsersForFolder(
2015 int $ref_id,
2016 int $active
2017 ): array {
2018 global $DIC;
2019 $ilDB = $DIC['ilDB'];
2020
2021 $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';
2022 $types[] = 'text';
2023 $values[] = 'language';
2024
2025 if (is_numeric($active) && $active > -1) {
2026 $query .= ' AND usr_data.active = %s';
2027 $values[] = $active;
2028 $types[] = 'integer';
2029 }
2030
2031 if ($ref_id != USER_FOLDER_ID) {
2032 $query .= ' AND usr_data.time_limit_owner = %s';
2033 $values[] = $ref_id;
2034 $types[] = 'integer';
2035 }
2036
2037 $query .= ' AND usr_data.usr_id != %s ';
2038 $values[] = ANONYMOUS_USER_ID;
2039 $types[] = 'integer';
2040
2041 $query .= ' ORDER BY usr_data.lastname, usr_data.firstname ';
2042
2043 $result = $ilDB->queryF($query, $types, $values);
2044 $data = [];
2045 while ($row = $ilDB->fetchAssoc($result)) {
2046 $data[] = $row;
2047 }
2048
2049 return $data;
2050 }
2051
2052 public static function _getUsersForGroup(
2053 array $a_mem_ids,
2054 int $active = -1
2055 ): array {
2056 return self::_getUsersForIds($a_mem_ids, $active);
2057 }
2058
2059 public static function _getUsersForIds(
2060 array $a_mem_ids,
2061 int $active = -1,
2062 int $timelimitowner = -1
2063 ): array {
2064 global $DIC;
2065 $ilDB = $DIC['ilDB'];
2066
2067 $query = 'SELECT usr_data.*, usr_pref.value AS language
2068 FROM usr_data
2069 LEFT JOIN usr_pref ON usr_pref.usr_id = usr_data.usr_id AND usr_pref.keyword = %s
2070 WHERE ' . $ilDB->in('usr_data.usr_id', $a_mem_ids, false, 'integer') . '
2071 AND usr_data.usr_id != %s';
2072 $values[] = 'language';
2073 $types[] = 'text';
2074 $values[] = ANONYMOUS_USER_ID;
2075 $types[] = 'integer';
2076
2077 if (is_numeric($active) && $active > -1) {
2078 $query .= ' AND active = %s';
2079 $values[] = $active;
2080 $types[] = 'integer';
2081 }
2082
2083 if ($timelimitowner != USER_FOLDER_ID && $timelimitowner != -1) {
2084 $query .= ' AND usr_data.time_limit_owner = %s';
2085 $values[] = $timelimitowner;
2086 $types[] = 'integer';
2087 }
2088
2089 $query .= ' ORDER BY usr_data.lastname, usr_data.firstname ';
2090
2091 $result = $ilDB->queryF($query, $types, $values);
2092 $mem_arr = [];
2093 while ($row = $ilDB->fetchAssoc($result)) {
2094 $mem_arr[] = $row;
2095 }
2096
2097 return $mem_arr;
2098 }
2099
2100 public static function _getUserData(array $a_internalids): array
2101 {
2102 global $DIC;
2103 $ilDB = $DIC['ilDB'];
2104
2105 $ids = [];
2106 if (is_array($a_internalids)) {
2107 foreach ($a_internalids as $internalid) {
2108 if (is_numeric($internalid)) {
2109 $ids[] = $internalid;
2110 } else {
2111 $parsedid = ilUtil::__extractId($internalid, IL_INST_ID);
2112 if (is_numeric($parsedid) && $parsedid > 0) {
2113 $ids[] = $parsedid;
2114 }
2115 }
2116 }
2117 }
2118 if (count($ids) == 0) {
2119 $ids [] = -1;
2120 }
2121
2122 $query = 'SELECT usr_data.*, usr_pref.value AS language
2123 FROM usr_data
2124 LEFT JOIN usr_pref
2125 ON usr_pref.usr_id = usr_data.usr_id AND usr_pref.keyword = %s
2126 WHERE ' . $ilDB->in('usr_data.usr_id', $ids, false, 'integer');
2127 $values[] = 'language';
2128 $types[] = 'text';
2129
2130 $query .= ' ORDER BY usr_data.lastname, usr_data.firstname ';
2131
2132 $data = [];
2133 $result = $ilDB->queryF($query, $types, $values);
2134 while ($row = $ilDB->fetchAssoc($result)) {
2135 $data[] = $row;
2136 }
2137 return $data;
2138 }
2139
2140 public static function _getPreferences(int $user_id): array
2141 {
2142 global $DIC;
2143 $ilDB = $DIC['ilDB'];
2144
2145 $prefs = [];
2146
2147 $r = $ilDB->queryF(
2148 'SELECT * FROM usr_pref WHERE usr_id = %s',
2149 ['integer'],
2150 [$user_id]
2151 );
2152
2153 while ($row = $ilDB->fetchAssoc($r)) {
2154 $prefs[$row['keyword']] = $row['value'];
2155 }
2156
2157 return $prefs;
2158 }
2159
2160 public static function getUserSubsetByPreferenceValue(
2161 array $a_user_ids,
2162 string $a_keyword,
2163 string $a_val
2164 ): array {
2165 global $DIC;
2166 $ilDB = $DIC['ilDB'];
2167
2168 $users = [];
2169 $set = $ilDB->query(
2170 'SELECT usr_id FROM usr_pref ' .
2171 ' WHERE keyword = ' . $ilDB->quote($a_keyword, 'text') .
2172 ' AND ' . $ilDB->in('usr_id', $a_user_ids, false, 'integer') .
2173 ' AND value = ' . $ilDB->quote($a_val, 'text')
2174 );
2175 while ($rec = $ilDB->fetchAssoc($set)) {
2176 $users[] = $rec['usr_id'];
2177 }
2178 return $users;
2179 }
2180
2181 public static function _getLoginAttempts(
2182 int $a_usr_id
2183 ): int {
2184 global $DIC;
2185 $ilDB = $DIC['ilDB'];
2186
2187 $query = 'SELECT login_attempts FROM usr_data WHERE usr_id = %s';
2188 $result = $ilDB->queryF($query, ['integer'], [$a_usr_id]);
2189 $record = $ilDB->fetchAssoc($result);
2190 return (int) ($record['login_attempts'] ?? 0);
2191 }
2192
2193 public static function _incrementLoginAttempts(
2194 int $a_usr_id
2195 ): bool {
2196 global $DIC;
2197 $ilDB = $DIC['ilDB'];
2198
2199 $query = 'UPDATE usr_data SET login_attempts = (login_attempts + 1) WHERE usr_id = %s';
2200 $affected = $ilDB->manipulateF($query, ['integer'], [$a_usr_id]);
2201
2202 if ($affected) {
2203 return true;
2204 } else {
2205 return false;
2206 }
2207 }
2208
2209 public static function _setUserInactive(
2210 int $a_usr_id
2211 ): bool {
2212 global $DIC;
2213 $ilDB = $DIC['ilDB'];
2214
2215 $query = 'UPDATE usr_data SET active = 0, inactivation_date = %s WHERE usr_id = %s';
2216 $affected = $ilDB->manipulateF($query, ['timestamp', 'integer'], [ilUtil::now(), $a_usr_id]);
2217
2218 if ($affected) {
2219 return true;
2220 } else {
2221 return false;
2222 }
2223 }
2224
2225 public static function _getUsersOnline(
2226 int $a_user_id = 0,
2227 bool $a_no_anonymous = false
2228 ): array {
2229 global $DIC;
2230 $ilDB = $DIC['ilDB'];
2231
2233
2234 $pd_set = new ilSetting('pd');
2235 $atime = $pd_set->get('user_activity_time') * 60;
2236 $ctime = time();
2237
2238 $where = [];
2239
2240 if ($a_user_id === 0) {
2241 $where[] = 'user_id > 0';
2242 } else {
2243 $where[] = 'user_id = ' . $ilDB->quote($a_user_id, 'integer');
2244 }
2245
2246 if ($a_no_anonymous) {
2247 $where[] = 'user_id != ' . $ilDB->quote(ANONYMOUS_USER_ID, 'integer');
2248 }
2249
2250 if (ilUserAccountSettings::getInstance()->isUserAccessRestricted()) {
2251 $where[] = $ilDB->in('time_limit_owner', ilUserFilter::getInstance()->getFolderIds(), false, 'integer');
2252 }
2253
2254 $where[] = 'expires > ' . $ilDB->quote($ctime, 'integer');
2255 $where[] = '(p.value IS NULL OR NOT p.value = ' . $ilDB->quote('y', 'text') . ')';
2256
2257 $where = 'WHERE ' . implode(' AND ', $where);
2258
2259 $r = $ilDB->queryF(
2260 $q = "
2261 SELECT COUNT(user_id) num, user_id, firstname, lastname, title, login, last_login, MAX(ctime) ctime, context, agree_date
2262 FROM usr_session
2263 LEFT JOIN usr_data u
2264 ON user_id = u.usr_id
2265 LEFT JOIN usr_pref p
2266 ON (p.usr_id = u.usr_id AND p.keyword = %s)
2267 {$where}
2268 GROUP BY user_id, firstname, lastname, title, login, last_login, context, agree_date
2269 ORDER BY lastname, firstname
2270 ",
2271 ['text'],
2272 ['hide_own_online_status']
2273 );
2274
2275 $log->debug('Query: ' . $q);
2276
2277 $users = [];
2278 while ($user = $ilDB->fetchAssoc($r)) {
2279 if ($atime <= 0 || $user['ctime'] + $atime > $ctime) {
2280 $users[$user['user_id']] = $user;
2281 }
2282 }
2283
2284 $log->debug('Found users: ' . count($users));
2285
2286 $hide_users = $DIC['legalDocuments']->usersWithHiddenOnlineStatus(array_map(intval(...), array_column($users, 'user_id')));
2287 $users = array_filter(
2288 $users,
2289 fn($user) => !in_array((int) $user['user_id'], $hide_users, true)
2290 );
2291
2292 return $users;
2293 }
2294
2295 public static function _verifyRegistrationHash(
2296 string $a_hash
2297 ): int {
2298 global $DIC;
2299 $db = $DIC['ilDB'];
2300
2301 $res = $db->queryf(
2302 'SELECT usr_id, create_date FROM usr_data WHERE reg_hash = %s',
2304 [$a_hash]
2305 );
2306
2307 $row = $db->fetchAssoc($res);
2308 if (!$row) {
2309 throw new ilRegistrationHashNotFoundException('reg_confirmation_hash_not_found');
2310 }
2311
2312 $lifetime = (new ilRegistrationSettings())->getRegistrationHashLifetime();
2313 if ($lifetime > 0) {
2314 $cutoff = (new DataFactory())->clock()->utc()
2315 ->now()->sub(
2316 new DateInterval("PT{$lifetime}S")
2317 );
2318
2319 $created = DateTimeImmutable::createFromFormat(
2320 self::DATABASE_DATE_FORMAT,
2321 (string) $row['create_date'],
2322 new DateTimeZone('UTC')
2323 );
2324
2325 if ($created === false || $created < $cutoff) {
2327 'reg_confirmation_hash_life_time_expired',
2328 (int) $row['usr_id']
2329 );
2330 }
2331 }
2332
2333 $db->manipulateF(
2334 'UPDATE usr_data SET reg_hash = NULL WHERE usr_id = %s',
2336 [(int) $row['usr_id']]
2337 );
2338
2339 return (int) $row['usr_id'];
2340 }
2341
2342 public static function getUserIdsByInactivityPeriod(
2343 int $periodInDays
2344 ): array {
2345 global $DIC;
2346 $ilDB = $DIC['ilDB'];
2347
2348 if ($periodInDays < 1) {
2349 throw new ilException('Invalid period given');
2350 }
2351
2352 $date = date('Y-m-d H:i:s', (time() - ($periodInDays * 24 * 60 * 60)));
2353
2354 $query = 'SELECT usr_id FROM usr_data WHERE last_login IS NOT NULL AND last_login < %s';
2355
2356 $ids = [];
2357
2358 $types = ['timestamp'];
2359 $values = [$date];
2360
2361 $res = $ilDB->queryF($query, $types, $values);
2362 while ($row = $ilDB->fetchAssoc($res)) {
2363 $ids[] = (int) $row['usr_id'];
2364 }
2365
2366 return $ids;
2367 }
2368
2369 public static function getUserIdsNeverLoggedIn(
2370 int $thresholdInDays
2371 ): array {
2372 global $DIC;
2373 $ilDB = $DIC['ilDB'];
2374
2375 $date = date('Y-m-d H:i:s', (time() - ($thresholdInDays * 24 * 60 * 60)));
2376
2377 $query = 'SELECT usr_id FROM usr_data WHERE last_login IS NULL AND create_date < %s';
2378
2379 $ids = [];
2380
2381 $types = ['timestamp'];
2382 $values = [$date];
2383
2384 $res = $ilDB->queryF($query, $types, $values);
2385 while ($row = $ilDB->fetchAssoc($res)) {
2386 $ids[] = (int) $row['usr_id'];
2387 }
2388
2389 return $ids;
2390 }
2391
2392 public static function _getUserIdsByInactivationPeriod(
2393 int $period
2394 ): array {
2395 if (!$period) {
2396 throw new ilException('no valid period given');
2397 }
2398
2399 global $DIC;
2400 $db = $DIC['ilDB'];
2401
2402 $res = $db->queryF(
2403 'SELECT usr_id FROM usr_data WHERE inactivation_date < %s AND active = %s',
2404 ['timestamp', 'integer'],
2405 [
2406 date('Y-m-d H:i:s', (time() - ($period * 24 * 60 * 60))),
2407 0
2408 ]
2409 );
2410
2411 $ids = [];
2412 while ($row = $db->fetchObject($res)) {
2413 $ids[] = (int) $row->usr_id;
2414 }
2415
2416 return $ids;
2417 }
2418
2419 public static function getFirstLettersOfLastnames(
2420 ?array $user_ids = null
2421 ): array {
2422 global $DIC;
2423 $ilDB = $DIC['ilDB'];
2424
2425 $q = 'SELECT DISTINCT ' . $ilDB->upper($ilDB->substr('lastname', 1, 1)) . ' let' .
2426 ' FROM usr_data' .
2427 ' WHERE usr_id <> ' . $ilDB->quote(ANONYMOUS_USER_ID, 'integer') .
2428 ($user_ids !== null ? ' AND ' . $ilDB->in('usr_id', $user_ids, false, 'integer') : '') .
2429 ' ORDER BY let';
2430 $let_set = $ilDB->query($q);
2431
2432 $let = [];
2433 while ($let_rec = $ilDB->fetchAssoc($let_set)) {
2434 $let[$let_rec['let']] = $let_rec['let'];
2435 }
2436 return $let;
2437 }
2438
2439 public static function userExists(
2440 array $a_usr_ids = []
2441 ): bool {
2442 global $DIC;
2443 $ilDB = $DIC['ilDB'];
2444
2445 $query = 'SELECT count(*) num FROM object_data od ' .
2446 'JOIN usr_data ud ON obj_id = usr_id ' .
2447 'WHERE ' . $ilDB->in('obj_id', $a_usr_ids, false, 'integer') . ' ';
2448 $res = $ilDB->query($query);
2449 $num_rows = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)->num;
2450 return $num_rows == count($a_usr_ids);
2451 }
2452
2453 public static function _doesLoginnameExistInHistory(string $a_login): bool
2454 {
2455 global $DIC;
2456 $ilDB = $DIC['ilDB'];
2457
2458 $res = $ilDB->queryF(
2459 '
2460 SELECT * FROM loginname_history
2461 WHERE login = %s',
2462 ['text'],
2463 [$a_login]
2464 );
2465
2466 return (bool) $ilDB->fetchAssoc($res);
2467 }
2468
2469 public static function _lookupPref(
2470 int $a_usr_id,
2471 string $a_keyword
2472 ): ?string {
2473 global $DIC;
2474 $ilDB = $DIC['ilDB'];
2475
2476 $query = 'SELECT * FROM usr_pref WHERE usr_id = ' . $ilDB->quote($a_usr_id, 'integer') . ' ' .
2477 'AND keyword = ' . $ilDB->quote($a_keyword, 'text');
2478 $res = $ilDB->query($query);
2479
2480 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
2481 return $row->value;
2482 }
2483 return null;
2484 }
2485
2486 public static function lookupMatriculation(int $a_usr_id): string
2487 {
2488 global $DIC;
2489 $ilDB = $DIC['ilDB'];
2490
2491 $query = 'SELECT matriculation FROM usr_data ' .
2492 'WHERE usr_id = ' . $ilDB->quote($a_usr_id);
2493 $res = $ilDB->query($query);
2494 $row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT);
2495 return $row->matriculation ?: '';
2496 }
2497
2498 public static function findInterests(
2499 string $a_term,
2500 ?int $a_user_id = null,
2501 ?string $a_field_id = null
2502 ): array {
2503 global $DIC;
2504 $ilDB = $DIC['ilDB'];
2505
2506 $res = [];
2507
2508 $sql = 'SELECT DISTINCT(value)' .
2509 ' FROM usr_profile_data' .
2510 ' WHERE ' . $ilDB->like('value', 'text', '%' . $a_term . '%');
2511 if ($a_field_id) {
2512 $sql .= ' AND field_id = ' . $ilDB->quote($a_field_id, 'text');
2513 }
2514 if ($a_user_id) {
2515 $sql .= ' AND usr_id <> ' . $ilDB->quote($a_user_id, 'integer');
2516 }
2517 $sql .= ' ORDER BY value';
2518 $set = $ilDB->query($sql);
2519 while ($row = $ilDB->fetchAssoc($set)) {
2520 $res[] = $row['value'];
2521 }
2522
2523 return $res;
2524 }
2525
2526 public static function getProfileStatusOfUsers(
2527 array $a_user_ids
2528 ): array {
2529 global $DIC;
2530 $ilDB = $DIC->database();
2531
2532 $set = $ilDB->query(
2533 'SELECT * FROM usr_pref ' .
2534 ' WHERE keyword = ' . $ilDB->quote('public_profile', 'text') .
2535 ' AND ' . $ilDB->in('usr_id', $a_user_ids, false, 'integer')
2536 );
2537 $r = [
2538 'global' => [],
2539 'local' => [],
2540 'public' => [],
2541 'not_public' => []
2542 ];
2543 while ($rec = $ilDB->fetchAssoc($set)) {
2544 if ($rec['value'] == 'g') {
2545 $r['global'][] = $rec['usr_id'];
2546 $r['public'][] = $rec['usr_id'];
2547 }
2548 if ($rec['value'] == 'y') {
2549 $r['local'][] = $rec['usr_id'];
2550 $r['public'][] = $rec['usr_id'];
2551 }
2552 }
2553 foreach ($a_user_ids as $id) {
2554 if (!in_array($id, $r['public'])) {
2555 $r['not_public'][] = $id;
2556 }
2557 }
2558
2559 return $r;
2560 }
2561
2562 private static function _lookup(
2563 int $a_user_id,
2564 string $a_field
2565 ): ?string {
2566 global $DIC;
2567 $ilDB = $DIC['ilDB'];
2568
2569 $res = $ilDB->queryF(
2570 'SELECT ' . $a_field . ' FROM usr_data WHERE usr_id = %s',
2571 ['integer'],
2572 [$a_user_id]
2573 );
2574
2575 while ($set = $ilDB->fetchAssoc($res)) {
2576 return $set[$a_field];
2577 }
2578 return null;
2579 }
2580
2581 public static function _lookupFullname(int $a_user_id): string
2582 {
2583 global $DIC;
2584 $ilDB = $DIC['ilDB'];
2585
2586 $fullname = '';
2587
2588 $set = $ilDB->queryF(
2589 'SELECT title, firstname, lastname FROM usr_data WHERE usr_id = %s',
2590 ['integer'],
2591 [$a_user_id]
2592 );
2593
2594 if ($rec = $ilDB->fetchAssoc($set)) {
2595 if ($rec['title']) {
2596 $fullname = $rec['title'] . ' ';
2597 }
2598 if ($rec['firstname']) {
2599 $fullname .= $rec['firstname'] . ' ';
2600 }
2601 if ($rec['lastname']) {
2602 $fullname .= $rec['lastname'];
2603 }
2604 }
2605 return $fullname;
2606 }
2607
2608 public static function _lookupEmail(int $a_user_id): string
2609 {
2610 return self::_lookup($a_user_id, 'email') ?? '';
2611 }
2612
2613 public static function _lookupGender(int $a_user_id): string
2614 {
2615 return (string) self::_lookup($a_user_id, 'gender') ?? '';
2616 }
2617
2618 public static function _lookupClientIP(int $a_user_id): string
2619 {
2620 return self::_lookup($a_user_id, 'client_ip') ?? '';
2621 }
2622
2623 public static function _lookupName(int $a_user_id): array
2624 {
2625 global $DIC;
2626 $ilDB = $DIC['ilDB'];
2627
2628 $res = $ilDB->queryF(
2629 'SELECT firstname, lastname, title, login FROM usr_data WHERE usr_id = %s',
2630 ['integer'],
2631 [$a_user_id]
2632 );
2633 if (($user_rec = $ilDB->fetchAssoc($res))) {
2634 return ['user_id' => $a_user_id,
2635 'firstname' => $user_rec['firstname'],
2636 'lastname' => $user_rec['lastname'],
2637 'title' => $user_rec['title'],
2638 'login' => $user_rec['login']
2639 ];
2640 }
2641 return ['user_id' => 0,
2642 'firstname' => '',
2643 'lastname' => '',
2644 'title' => '',
2645 'login' => ''
2646 ];
2647 }
2648
2649 public static function _lookupLanguage(int $a_usr_id): string
2650 {
2651 global $DIC;
2652 $ilDB = $DIC['ilDB'];
2653 $lng = $DIC['lng'];
2654
2655 $q = 'SELECT value FROM usr_pref WHERE usr_id= ' .
2656 $ilDB->quote($a_usr_id, 'integer') . ' AND keyword = ' .
2657 $ilDB->quote('language', 'text');
2658 $r = $ilDB->query($q);
2659
2660 while ($row = $ilDB->fetchAssoc($r)) {
2661 return (string) $row['value'];
2662 }
2663 if (is_object($lng)) {
2664 return $lng->getDefaultLanguage();
2665 }
2666 return 'en';
2667 }
2668
2669 public static function _writeExternalAccount(
2670 int $a_usr_id,
2671 string $a_ext_id
2672 ): void {
2673 global $DIC;
2674 $ilDB = $DIC['ilDB'];
2675
2676 $ilDB->manipulateF(
2677 'UPDATE usr_data ' .
2678 ' SET ext_account = %s WHERE usr_id = %s',
2679 ['text', 'integer'],
2680 [$a_ext_id, $a_usr_id]
2681 );
2682 }
2683
2684 public static function _writeAuthMode(int $a_usr_id, string $a_auth_mode): void
2685 {
2686 global $DIC;
2687 $ilDB = $DIC['ilDB'];
2688
2689 $ilDB->manipulateF(
2690 'UPDATE usr_data ' .
2691 ' SET auth_mode = %s WHERE usr_id = %s',
2692 ['text', 'integer'],
2693 [$a_auth_mode, $a_usr_id]
2694 );
2695 }
2696
2700 public static function _lookupFields(int $a_user_id): array // Missing array type.
2701 {
2702 global $DIC;
2703 $ilDB = $DIC['ilDB'];
2704
2705 $res = $ilDB->queryF(
2706 'SELECT * FROM usr_data WHERE usr_id = %s',
2707 ['integer'],
2708 [$a_user_id]
2709 );
2710 $user_rec = $ilDB->fetchAssoc($res);
2711 return $user_rec;
2712 }
2713
2714 public static function _lookupActive(int $a_usr_id): bool
2715 {
2716 global $DIC;
2717 $ilDB = $DIC['ilDB'];
2718
2719 $query = 'SELECT usr_id FROM usr_data ' .
2720 'WHERE active = ' . $ilDB->quote(1, 'integer') . ' ' .
2721 'AND usr_id = ' . $ilDB->quote($a_usr_id, 'integer');
2722 $res = $ilDB->query($query);
2723 while ($res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
2724 return true;
2725 }
2726 return false;
2727 }
2728
2729 public static function _lookupLogin(int $a_user_id): string
2730 {
2731 return (string) self::_lookup($a_user_id, 'login') ?? '';
2732 }
2733
2734 public static function _lookupExternalAccount(int $a_user_id): string
2735 {
2736 return (string) self::_lookup($a_user_id, 'ext_account') ?? '';
2737 }
2738
2745 public static function _getExternalAccountsByAuthMode(
2746 string $a_auth_mode,
2747 bool $a_read_auth_default = false
2748 ): array {
2749 global $DIC;
2750
2751 $ilDB = $DIC['ilDB'];
2752 $ilSetting = $DIC['ilSetting'];
2753
2754 $q = 'SELECT login,usr_id,ext_account,auth_mode FROM usr_data ' .
2755 'WHERE auth_mode = %s';
2756 $types[] = 'text';
2757 $values[] = $a_auth_mode;
2758 if ($a_read_auth_default and ilAuthUtils::_getAuthModeName($ilSetting->get('auth_mode', ilAuthUtils::AUTH_LOCAL)) == $a_auth_mode) {
2759 $q .= ' OR auth_mode = %s ';
2760 $types[] = 'text';
2761 $values[] = 'default';
2762 }
2763
2764 $res = $ilDB->queryF($q, $types, $values);
2765 $accounts = [];
2766 while ($row = $ilDB->fetchObject($res)) {
2767 if ($row->auth_mode == 'default') {
2768 $accounts[$row->usr_id] = $row->login;
2769 } else {
2770 $accounts[$row->usr_id] = $row->ext_account;
2771 }
2772 }
2773 return $accounts;
2774 }
2775
2776 public static function _toggleActiveStatusOfUsers(
2777 array $a_usr_ids,
2778 bool $a_status
2779 ): void {
2780 global $DIC;
2781
2782 $ilDB = $DIC['ilDB'];
2783
2784 if ($a_status) {
2785 $q = 'UPDATE usr_data SET active = 1, inactivation_date = NULL WHERE ' .
2786 $ilDB->in('usr_id', $a_usr_ids, false, 'integer');
2787 $ilDB->manipulate($q);
2788 } else {
2789 $usrId_IN_usrIds = $ilDB->in('usr_id', $a_usr_ids, false, 'integer');
2790
2791 $q = 'UPDATE usr_data SET active = 0 WHERE $usrId_IN_usrIds';
2792 $ilDB->manipulate($q);
2793
2794 $queryString = '
2795 UPDATE usr_data
2796 SET inactivation_date = %s
2797 WHERE inactivation_date IS NULL
2798 AND $usrId_IN_usrIds
2799 ';
2800 $ilDB->manipulateF($queryString, ['timestamp'], [ilUtil::now()]);
2801 }
2802 }
2803
2804 public static function _lookupAuthMode(int $a_usr_id): string
2805 {
2806 return (string) self::_lookup($a_usr_id, 'auth_mode');
2807 }
2808
2813 public static function _checkExternalAuthAccount(
2814 string $a_auth,
2815 string $a_account,
2816 bool $tryFallback = true
2817 ): ?string {
2818 $db = $GLOBALS['DIC']->database();
2819 $settings = $GLOBALS['DIC']->settings();
2820
2821 // Check directly with auth_mode
2822 $r = $db->queryF(
2823 'SELECT * FROM usr_data WHERE ' .
2824 ' ext_account = %s AND auth_mode = %s',
2825 ['text', 'text'],
2826 [$a_account, $a_auth]
2827 );
2828 if ($usr = $db->fetchAssoc($r)) {
2829 return $usr['login'];
2830 }
2831
2832 if (!$tryFallback) {
2833 return null;
2834 }
2835
2836 // For compatibility, check for login (no ext_account entry given)
2837 $res = $db->queryF(
2838 'SELECT login FROM usr_data ' .
2839 'WHERE login = %s AND auth_mode = %s AND (ext_account IS NULL OR ext_account = "") ',
2840 ['text', 'text'],
2841 [$a_account, $a_auth]
2842 );
2843 if ($usr = $db->fetchAssoc($res)) {
2844 return $usr['login'];
2845 }
2846
2847 // If auth_default == $a_auth => check for login
2848 if (ilAuthUtils::_getAuthModeName($settings->get('auth_mode')) == $a_auth) {
2849 $res = $db->queryF(
2850 'SELECT login FROM usr_data WHERE ' .
2851 ' ext_account = %s AND auth_mode = %s',
2852 ['text', 'text'],
2853 [$a_account, 'default']
2854 );
2855 if ($usr = $db->fetchAssoc($res)) {
2856 return $usr['login'];
2857 }
2858 // Search for login (no ext_account given)
2859 $res = $db->queryF(
2860 'SELECT login FROM usr_data ' .
2861 'WHERE login = %s AND (ext_account IS NULL OR ext_account = "") AND auth_mode = %s',
2862 ['text', 'text'],
2863 [$a_account, 'default']
2864 );
2865 if ($usr = $db->fetchAssoc($res)) {
2866 return $usr['login'];
2867 }
2868 }
2869 return null;
2870 }
2871
2872 public static function getUserIdByLogin(string $a_login): int
2873 {
2874 return (int) self::_lookupId($a_login);
2875 }
2876
2877 public static function getUserIdsByEmail(string $a_email): array
2878 {
2879 global $DIC;
2880 $ilDB = $DIC['ilDB'];
2881
2882 $res = $ilDB->queryF(
2883 'SELECT usr_id FROM usr_data ' .
2884 'WHERE email = %s and active = 1',
2885 ['text'],
2886 [$a_email]
2887 );
2888 $ids = [];
2889 while ($row = $ilDB->fetchObject($res)) {
2890 $ids[] = (int) $row->usr_id;
2891 }
2892
2893 return $ids;
2894 }
2895
2896 public static function getUserLoginsByEmail(string $a_email): array
2897 {
2898 global $DIC;
2899 $ilDB = $DIC['ilDB'];
2900
2901 $res = $ilDB->queryF(
2902 'SELECT login FROM usr_data ' .
2903 'WHERE email = %s and active = 1',
2904 ['text'],
2905 [$a_email]
2906 );
2907 $ids = [];
2908 while ($row = $ilDB->fetchObject($res)) {
2909 $ids[] = $row->login;
2910 }
2911
2912 return $ids;
2913 }
2914
2915 public static function _lookupId(
2916 string|array $a_user_str
2917 ): int|null|array {
2918 global $DIC;
2919 $ilDB = $DIC['ilDB'];
2920
2921 if (!is_array($a_user_str)) {
2922 $res = $ilDB->queryF(
2923 'SELECT usr_id FROM usr_data WHERE login = %s',
2924 ['text'],
2925 [$a_user_str]
2926 );
2927
2928 $user_rec = $ilDB->fetchAssoc($res);
2929 if (is_array($user_rec)) {
2930 return (int) $user_rec['usr_id'];
2931 }
2932
2933 return null;
2934 }
2935
2936 $set = $ilDB->query(
2937 'SELECT usr_id FROM usr_data ' .
2938 ' WHERE ' . $ilDB->in('login', $a_user_str, false, 'text')
2939 );
2940
2941 $ids = [];
2942 while ($rec = $ilDB->fetchAssoc($set)) {
2943 $ids[] = (int) $rec['usr_id'];
2944 }
2945
2946 return $ids;
2947 }
2948
2949 public static function _lookupLastLogin(int $a_user_id): string
2950 {
2951 return self::_lookup($a_user_id, 'last_login') ?? '';
2952 }
2953
2954 public static function _lookupFirstLogin(int $a_user_id): string
2955 {
2956 return self::_lookup($a_user_id, 'first_login') ?? '';
2957 }
2958
2959 public static function hasActiveSession(
2960 int $a_user_id,
2961 string $a_session_id
2962 ): bool {
2963 global $DIC;
2964 $ilDB = $DIC['ilDB'];
2965
2966 $set = $ilDB->queryf(
2967 '
2968 SELECT COUNT(*) session_count
2969 FROM usr_session WHERE user_id = %s AND expires > %s AND session_id != %s ',
2970 ['integer', 'integer', 'text'],
2971 [$a_user_id, time(), $a_session_id]
2972 );
2973 $row = $ilDB->fetchAssoc($set);
2974 return (bool) $row['session_count'];
2975 }
2976
2977 public static function _readUsersProfileData(array $a_user_ids): array
2978 {
2979 global $DIC;
2980 $ilDB = $DIC['ilDB'];
2981
2982 $res = $ilDB->query('SELECT * FROM usr_data WHERE ' .
2983 $ilDB->in('usr_id', $a_user_ids, false, 'integer'));
2984 $user_data = [];
2985 while ($row = $ilDB->fetchAssoc($res)) {
2986 $user_data[$row['usr_id']] = $row;
2987 }
2988 return $user_data;
2989 }
2990
2991 public static function _getNumberOfUsersForStyle(
2992 string $a_skin,
2993 string $a_style
2994 ): int {
2995 global $DIC;
2996 $ilDB = $DIC['ilDB'];
2997
2998 $q = 'SELECT count(*) as cnt FROM usr_pref up1, usr_pref up2 ' .
2999 ' WHERE up1.keyword= ' . $ilDB->quote('style', 'text') .
3000 ' AND up1.value= ' . $ilDB->quote($a_style, 'text') .
3001 ' AND up2.keyword= ' . $ilDB->quote('skin', 'text') .
3002 ' AND up2.value= ' . $ilDB->quote($a_skin, 'text') .
3003 ' AND up1.usr_id = up2.usr_id ';
3004
3005 $cnt_set = $ilDB->query($q);
3006
3007 $cnt_rec = $ilDB->fetchAssoc($cnt_set);
3008
3009 return (int) $cnt_rec['cnt'];
3010 }
3011
3012 public static function _getAllUserAssignedStyles(): array
3013 {
3014 global $DIC;
3015 $ilDB = $DIC['ilDB'];
3016
3017 $q = 'SELECT DISTINCT up1.value style, up2.value skin FROM usr_pref up1, usr_pref up2 ' .
3018 ' WHERE up1.keyword = ' . $ilDB->quote('style', 'text') .
3019 ' AND up2.keyword = ' . $ilDB->quote('skin', 'text') .
3020 ' AND up1.usr_id = up2.usr_id';
3021
3022 $sty_set = $ilDB->query($q);
3023
3024 $styles = [];
3025 while ($sty_rec = $ilDB->fetchAssoc($sty_set)) {
3026 $styles[] = $sty_rec['skin'] . ':' . $sty_rec['style'];
3027 }
3028
3029 return $styles;
3030 }
3031
3035 public static function _getNumberOfUsersPerAuthMode(): array // Missing array type.
3036 {
3037 global $DIC;
3038
3039 $ilDB = $DIC['ilDB'];
3040
3041 $r = $ilDB->query('SELECT count(*) AS cnt, auth_mode FROM usr_data ' .
3042 'GROUP BY auth_mode');
3043 $cnt_arr = [];
3044 while ($cnt = $ilDB->fetchAssoc($r)) {
3045 $cnt_arr[$cnt['auth_mode']] = (int) $cnt['cnt'];
3046 }
3047
3048 return $cnt_arr;
3049 }
3050
3051 public static function _getLocalAccountsForEmail(string $a_email): array // Missing array type.
3052 {
3053 global $DIC;
3054
3055 $ilDB = $DIC['ilDB'];
3056 $ilSetting = $DIC['ilSetting'];
3057
3058 // default set to local (1)?
3059
3060 $q = 'SELECT * FROM usr_data WHERE ' .
3061 ' email = %s AND (auth_mode = %s ';
3062 $types = ['text', 'text'];
3063 $values = [$a_email, 'local'];
3064
3065 if ($ilSetting->get('auth_mode') == 1) {
3066 $q .= ' OR auth_mode = %s';
3067 $types[] = 'text';
3068 $values[] = 'default';
3069 }
3070
3071 $q .= ')';
3072
3073 $users = [];
3074 $usr_set = $ilDB->queryF($q, $types, $values);
3075 while ($usr_rec = $ilDB->fetchAssoc($usr_set)) {
3076 $users[$usr_rec['usr_id']] = $usr_rec['login'];
3077 }
3078
3079 return $users;
3080 }
3081
3082 public static function _moveUsersToStyle(
3083 string $a_from_skin,
3084 string $a_from_style,
3085 string $a_to_skin,
3086 string $a_to_style
3087 ): void {
3088 global $DIC;
3089 $ilDB = $DIC['ilDB'];
3090
3091 $q = 'SELECT up1.usr_id usr_id FROM usr_pref up1, usr_pref up2 ' .
3092 ' WHERE up1.keyword= ' . $ilDB->quote('style', 'text') .
3093 ' AND up1.value= ' . $ilDB->quote($a_from_style, 'text') .
3094 ' AND up2.keyword= ' . $ilDB->quote('skin', 'text') .
3095 ' AND up2.value= ' . $ilDB->quote($a_from_skin, 'text') .
3096 ' AND up1.usr_id = up2.usr_id ';
3097
3098 $usr_set = $ilDB->query($q);
3099
3100 while ($usr_rec = $ilDB->fetchAssoc($usr_set)) {
3101 $ilDB->replace(
3102 'usr_pref',
3103 [
3104 'usr_id' => [ilDBConstants::T_INTEGER, $usr_rec['usr_id']],
3105 'keyword' => [ilDBConstants::T_TEXT, 'skin'],
3106 ],
3107 [
3108 'value' => [ilDBConstants::T_TEXT, $a_to_skin]
3109 ]
3110 );
3111 $ilDB->replace(
3112 'usr_pref',
3113 [
3114 'usr_id' => [ilDBConstants::T_INTEGER, $usr_rec['usr_id']],
3115 'keyword' => [ilDBConstants::T_TEXT, 'style'],
3116 ],
3117 [
3118 'value' => [ilDBConstants::T_TEXT, $a_to_style]
3119 ]
3120 );
3121 }
3122 }
3123
3124 public static function _getUsersForClipboadObject(
3125 string $a_type,
3126 int $a_id
3127 ): array {
3128 global $DIC;
3129 $ilDB = $DIC['ilDB'];
3130
3131 $q = 'SELECT DISTINCT user_id FROM personal_clipboard WHERE ' .
3132 'item_id = ' . $ilDB->quote($a_id, 'integer') . ' AND ' .
3133 'type = ' . $ilDB->quote($a_type, 'text');
3134 $user_set = $ilDB->query($q);
3135 $users = [];
3136 while ($user_rec = $ilDB->fetchAssoc($user_set)) {
3137 $users[] = (int) $user_rec['user_id'];
3138 }
3139
3140 return $users;
3141 }
3142
3143 public static function _getImportedUserId(
3144 string $i2_id
3145 ): int {
3146 global $DIC;
3147 $ilDB = $DIC['ilDB'];
3148
3149 $query = 'SELECT obj_id FROM object_data WHERE import_id = ' .
3150 $ilDB->quote($i2_id, 'text');
3151
3152 $res = $ilDB->query($query);
3153 $id = 0;
3154 while ($row = $ilDB->fetchObject($res)) {
3155 $id = (int) $row->obj_id;
3156 }
3157 return $id;
3158 }
3159
3160 public static function lookupOrgUnitsRepresentation(
3161 int $a_usr_id
3162 ): string {
3163 return ilOrgUnitPathStorage::getTextRepresentationOfUsersOrgUnits($a_usr_id);
3164 }
3165
3166 public static function _getAvatar(int $a_usr_id): Avatar
3167 {
3168 $define = new ilUserAvatarResolver($a_usr_id ?: ANONYMOUS_USER_ID);
3169 $define->setSize('xsmall');
3170 return $define->getAvatar();
3171 }
3172
3173 public static function _getPersonalPicturePath(
3174 int $a_usr_id,
3175 string $a_size = 'small',
3176 bool $a_force_pic = false
3177 ): string {
3178 $define = new ilUserAvatarResolver($a_usr_id);
3179 $define->setForcePicture($a_force_pic);
3180 $define->setSize($a_size);
3181 return $define->getLegacyPictureURL();
3182 }
3183
3184 public static function copyProfilePicturesToDirectory(
3185 int $a_user_id,
3186 string $a_dir
3187 ): void {
3188 global $DIC;
3189 $irss = $DIC->resourceStorage();
3190
3191 $clean_dir = trim(str_replace('..', '', $a_dir));
3192 if ($clean_dir == '' || !is_dir($clean_dir)) {
3193 return;
3194 }
3195 $avatar_rid = (new ilObjUser($a_user_id))->getAvatarRid();
3196 if ($avatar_rid === null) {
3197 return;
3198 }
3199
3200 file_put_contents(
3201 $clean_dir . '/usr_' . $a_user_id . '.jpg',
3202 $irss->consume()->stream($avatar_rid)->getStream()->getContents()
3203 );
3204 }
3205
3206 public static function _lookupFeedHash(
3207 int $a_user_id,
3208 bool $a_create = false
3209 ): ?string {
3210 global $DIC;
3211 $ilDB = $DIC['ilDB'];
3212
3213 if ($a_user_id > 0) {
3214 $set = $ilDB->queryF(
3215 'SELECT feed_hash from usr_data WHERE usr_id = %s',
3216 ['integer'],
3217 [$a_user_id]
3218 );
3219 if ($rec = $ilDB->fetchAssoc($set)) {
3220 if (strlen($rec['feed_hash']) == 32) {
3221 return $rec['feed_hash'];
3222 } elseif ($a_create) {
3223 $hash = md5(random_int(1, 9999999) + str_replace(' ', '', microtime()));
3224 $ilDB->manipulateF(
3225 'UPDATE usr_data SET feed_hash = %s' .
3226 ' WHERE usr_id = %s',
3227 ['text', 'integer'],
3228 [$hash, $a_user_id]
3229 );
3230 return $hash;
3231 }
3232 }
3233 }
3234 return null;
3235 }
3236
3237 public static function _getFeedPass(
3238 int $a_user_id
3239 ): ?string {
3240 if ($a_user_id > 0) {
3241 return self::_lookupPref($a_user_id, 'priv_feed_pass');
3242 }
3243 return null;
3244 }
3245}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
A Date Format provides a format definition akin to PHP's date formatting options, but stores the sing...
Definition: DateFormat.php:27
Builds data types.
Definition: Factory.php:36
Stream factory which enables the user to create streams without the knowledge of the concrete class.
Definition: Streams.php:32
const IL_CAL_UNIX
const IL_CAL_DATETIME
const int AUTH_LOCAL
static _needsExternalAccountByAuthMode($a_auth_mode)
Check if chosen auth mode needs an external account entry.
static _getAuthMode(?string $a_auth_mode)
static _getAuthModeName($a_auth_key)
static deleteByUserId(int $a_user_id)
static _deleteSettingsOfUser(int $a_user)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilCtrl provides processing control methods.
Class ilDBConstants.
static resetToDefaults()
reset to defaults
static setUseRelativeDates(bool $a_status)
set use relative dates
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ?ilObjUser $user=null,)
static formatPeriod(ilDateTime $start, ilDateTime $end, bool $a_skip_starting_day=false, ?ilObjUser $user=null)
Format a period of two dates Shows: 14.
static setLanguage(ilLanguage $a_lng)
@classDescription Date and time handling
static _deleteByUser(int $a_usr_id)
Base class for ILIAS Exception handling.
static _getExportDirectory(int $a_obj_id, string $a_type="xml", string $a_obj_type="", string $a_entity="")
@depricated Get export directory for an repository object
static deliverFileLegacy(string $a_file, ?string $a_filename=null, ?string $a_mime=null, ?bool $isInline=false, ?bool $removeAfterDelivery=false, ?bool $a_exit_after=true)
static getDir(string $a_dir, bool $a_rec=false, ?string $a_sub_dir="")
get directory
Import class.
addSkipImporter(string $a_component, bool $skip=true)
static _getInstance()
Get singleton instance of this class.
static getLogger(string $a_component_id)
Get component logger.
static lookupTitle(int $a_page_id)
static removeForUser(int $user_id)
Remove all notifications for given user.
static _deleteUser(int $a_usr_id)
static deleteUserPortfolios(int $a_user_id)
Delete all portfolio data for user.
static _removeTrackingDataForUser(int $user_id)
to be called from IlObjUser
static _deleteUser(int $a_usr_id)
User class.
static _lookupLanguage(int $a_usr_id)
DataFactory $data_factory
__construct(int $a_user_id=0, bool $a_call_by_reference=false)
setLastProfilePrompt(string $date)
static getUserIdsNeverLoggedIn(int $thresholdInDays)
static _isAnonymous(int $usr_id)
getClipboardObjects(string $a_type='', bool $a_top_nodes_only=false)
get all clipboard objects of user and specified type
setGender(string $gender_string)
getPersonalPicturePath(string $a_size='small', bool $a_force_pic=false)
assignSystemInformationFromDB(array $data)
string $last_login
static _getUsersOnline(int $a_user_id=0, bool $a_no_anonymous=false)
static _lookup(int $a_user_id, string $a_field)
StreamDelivery $delivery
setAvatarRid(?ResourceIdentification $avatar_rid)
getOfferingHelpAsText()
Get help offering as plain text.
setPhoneMobile(string $phone)
static lookupMatriculation(int $a_usr_id)
static getUserLoginsByEmail(string $a_email)
string $client_ip
setIsSelfRegistered(bool $status)
setPref(string $a_keyword, ?string $a_value)
setLongitude(?string $longitude)
setLanguage(string $language)
buildTextFromArray(array $a_attr)
updateLogin(string $login)
const DATABASE_DATE_FORMAT
setAuthMode(?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)
getAuthMode(bool $a_auth_key=false)
setLogin(string $login)
getPref(string $a_keyword)
setStreet(string $street)
static _getUsersForIds(array $a_mem_ids, int $active=-1, int $timelimitowner=-1)
setEmail(string $email)
ilSetting $settings
setLastLogin(string $a_str)
setCity(string $city)
static _verifyRegistrationHash(string $a_hash)
setFirstLogin(string $date)
static userExists(array $a_usr_ids=[])
clipboardHasObjectsOfType(string $a_type)
Check whether clipboard has objects of a certain type.
string $password_encoding_type
writeHistory(string $login)
setInactivationDate(?string $inactivation_date)
setTimeLimitUntil(?int $a_until)
static _lookupActive(int $a_usr_id)
prepareAndRetrievePasswordForStorage()
static _externalAccountExists(string $a_external_account, string $a_auth_mode)
setPasswordSalt(?string $password_salt)
setLastPasswordChangeTS(int $a_last_password_change_ts)
string $agree_date
bool $is_self_registered
setTimeLimitFrom(?int $a_from)
string $inactivation_date
getCurrentLanguage()
returns the current language (may differ from user's pref setting!)
setLatitude(?string $latitude)
static _getLoginAttempts(int $a_usr_id)
setPhoneHome(string $phone)
static _toggleActiveStatusOfUsers(array $a_usr_ids, bool $a_status)
setPasswordEncodingType(?string $password_encryption_type)
static _lookupFullname(int $a_user_id)
static _writeExternalAccount(int $a_usr_id, string $a_ext_id)
const PASSWD_CRYPTED
static _getNumberOfUsersForStyle(string $a_skin, string $a_style)
static _getLocalAccountsForEmail(string $a_email)
getProfileAsString(Language $language)
Get formatted mail body text of user profile data.
getFullname(int $max_strlen=0)
bool $time_limit_unlimited
bool $passwd_policy_reset
static _getUserData(array $a_internalids)
setHobby(string $hobby)
int $time_limit_from
int $last_password_change_ts
setFax(string $fax)
setPasswordPolicyResetStatus(bool $status)
string $first_login
static _getAllUserAssignedStyles()
setMatriculation(string $matriculation)
setComment(string $referral_comment)
setPasswd(string $a_str, string $a_type=ilObjUser::PASSWD_PLAIN)
string $ext_account
static getUserIdsByEmail(string $a_email)
static _lookupExternalAccount(int $a_user_id)
string $approve_date
ProfileConfigurationRepository $profile_configuration_repository
setActive(bool $active, int $owner=0)
set user active state and updates system fields appropriately
static _lookupFirstLogin(int $a_user_id)
string $passwd_type
static _getNumberOfUsersPerAuthMode()
get number of users per auth mode
static _lookupAuthMode(int $a_usr_id)
getPasswordPolicyResetStatus()
setSecondEmail(?string $email)
setZipcode(string $zipcode)
setTimeLimitOwner(int $a_owner)
setLastname(string $lastname)
static findInterests(string $a_term, ?int $a_user_id=null, ?string $a_field_id=null)
Data $profile_data
setLookingForHelp(?array $value=null)
deletePref(string $keyword)
setCountry(string $country)
const PASSWD_PLAIN
static _getUsersForClipboadObject(string $a_type, int $a_id)
int $time_limit_until
static _incrementLoginAttempts(int $a_usr_id)
static _lookupName(int $a_user_id)
setBirthday(?string $birthday)
withProfileData(Data $profile_data)
static _lookupId(string|array $a_user_str)
string $password_salt
static _lookupFeedHash(int $a_user_id, bool $a_create=false)
retrieveAgreeDateForStorage()
setLocationZoom(?int $zoom)
static _getUsersForFolder(int $ref_id, int $active)
Services $irss
static _moveUsersToStyle(string $a_from_skin, string $a_from_style, string $a_to_skin, string $a_to_style)
int $time_limit_owner
removeObjectFromClipboard(int $a_item_id, string $a_type)
setDepartment(string $department)
static _getPreferences(int $user_id)
static getProfileStatusOfUsers(array $a_user_ids)
static _lookupPref(int $a_usr_id, string $a_keyword)
clipboardDeleteObjectsOfType(string $a_type)
static _getImportedUserId(string $i2_id)
setPhoneOffice(string $phone)
buildSystemInformationArrayForDB()
static _lookupLastLogin(int $a_user_id)
string $passwd
ilAuthSession $auth_session
setGeneralInterests(?array $value=null)
setProfileIncomplete(bool $a_prof_inc)
setLastUpdate(string $date)
static _getPersonalPicturePath(int $a_usr_id, string $a_size='small', bool $a_force_pic=false)
writePref(string $keyword, string $value)
setExternalAccount(string $a_str)
static hasActiveSession(int $a_user_id, string $a_session_id)
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's personal clipboard
static _getUsersForGroup(array $a_mem_ids, int $active=-1)
static _lookupFields(int $a_user_id)
setAgreeDate(?string $date)
string $last_profile_prompt
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...
setTimeLimitUnlimited(bool $unlimited)
static getUserIdByLogin(string $a_login)
static _getFeedPass(int $a_user_id)
static _lookupClientIP(int $a_user_id)
static _lookupLogin(int $a_user_id)
string $fullname
string $auth_mode
bool $profile_incomplete
resetPassword(string $new_raw_password)
setLastPasswordChangeToNow()
setLoginAttempts(int $a_login_attempts)
static _writeAuthMode(int $a_usr_id, string $a_auth_mode)
static _lookupGender(int $a_user_id)
static _checkExternalAuthAccount(string $a_auth, string $a_account, bool $tryFallback=true)
check whether external account and authentication method matches with a user
static _getUsersForRole(int $role_id, int $active=-1)
static _loginExists(string $a_login, int $a_user_id=0)
static lookupOrgUnitsRepresentation(int $a_usr_id)
getGeneralInterestsAsText()
Get general interests as plain text.
setFeedPass(string $a_password)
getPCClipboardContent()
Add a page content item to PC clipboard (should go to another class)
static _doesLoginnameExistInHistory(string $a_login)
static _setUserInactive(int $a_usr_id)
setOfferingHelp(?array $value=null)
getClipboardChilds(int $a_parent, string $a_insert_time)
Get children of an item.
uploadPersonalPicture(string $tmp_file)
static getUserSubsetByPreferenceValue(array $a_user_ids, string $a_keyword, string $a_val)
setClientIP(string $a_str)
setInstitution(string $instituion)
static getUserIdsByInactivityPeriod(int $periodInDays)
setFirstname(string $firstname)
static _readUsersProfileData(array $a_user_ids)
setCurrentLanguage(string $language)
Set current language.
static array $personal_image_cache
static getFirstLettersOfLastnames(?array $user_ids=null)
setUTitle(string $user_title)
This sets the USER's title NOT the OBJECT's title!
importPersonalData(array $a_file, bool $a_profile_data, bool $a_settings, bool $a_notes, bool $a_calendar)
static _getAvatar(int $a_usr_id)
static copyProfilePicturesToDirectory(int $a_user_id, string $a_dir)
ProfileDataRepository $profile_data_repository
setApproveDate(?string $a_str)
set date the user account was activated null indicates that the user has not yet been activated
ilCronDeleteInactiveUserReminderMail $cron_delete_user_reminder_mail
static _lookupEmail(int $a_user_id)
static _getUserIdsByInactivationPeriod(int $period)
Class ilObject Basic functions for all objects.
static _lookupType(int $id, bool $reference=false)
string $create_date
updateOwner()
update owner of object in db
setId(int $id)
string $last_update
static _lookupTitle(int $obj_id)
Class ilOrgUnitPathStorage.
static _exists(string $a_parent_type, int $a_id, string $a_lang="", bool $a_no_cache=false)
Checks whether page exists.
Class for user related exception handling in ILIAS.
Class for user related exception handling in ILIAS.
Class ilObjAuthSettingsGUI.
static _removeTrackingDataForUser(int $user_id)
static _getInstance()
Get instance of ilSecuritySettings.
static _destroyByUserId(int $a_user_id)
Destroy session.
static get(string $a_var)
static clear(string $a_var)
static set(string $a_var, $a_val)
Set a value.
ILIAS Setting Class.
get(string $a_keyword, ?string $a_default_value=null)
get setting
static skinExists(string $skin_id, ?ilSystemStyleConfig $system_style_config=null)
Check whether a skin exists.
static styleExists(string $style_id)
static styleExistsForSkinId(string $skin_id, string $style_id)
Class ilUserAvatarResolver.
setForcePicture(bool $force_image)
There are places where we want wo show the Profile Picture of a User, even if the user doesn't want t...
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
static now()
Return current timestamp in Y-m-d H:i:s format.
static __extractId(string $ilias_id, int $inst_id)
extract ref id from role title, e.g.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const USER_FOLDER_ID
Definition: constants.php:33
const SYSTEM_USER_ID
This file contains constants for PHPStan analyis, see: https://phpstan.org/config-reference#constants...
Definition: constants.php:26
const IL_INST_ID
Definition: constants.php:40
const ANONYMOUS_USER_ID
Definition: constants.php:27
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
loadLanguageModule(string $a_module)
txt(string $a_topic, string $a_default_lang_fallback_mod="")
This describes how a letter or a picture avatar could be modified during construction of UI.
Definition: Avatar.php:29
$ref_id
Definition: ltiauth.php:66
$log
Definition: ltiresult.php:34
$res
Definition: ltiservices.php:69
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Class ilObjForumAdministration.
global $lng
Definition: privfeed.php:31
global $ilSetting
Definition: privfeed.php:31
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26
$q
Definition: shib_logout.php:23
$GLOBALS["DIC"]
Definition: wac.php:54