ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilPersonalProfileGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
31 
38 {
39  private const PERSONAL_DATA_FORM_ID = 'pd';
40  public const CHANGE_EMAIL_CMD = 'changeEmail';
41 
46  private string $password_error;
47  private string $upload_error;
49  private ilObjUser $user;
51 
52  private ilLanguage $lng;
53  private ilCtrl $ctrl;
54  private ilTabsGUI $tabs;
56  private ilHelpGUI $help;
63 
66 
68  private IRSS $irss;
70 
72 
73  public function __construct(
74  ) {
76  global $DIC;
77 
78  $this->tabs = $DIC['ilTabs'];
79  $this->toolbar = $DIC['ilToolbar'];
80  $this->help = $DIC['ilHelp'];
81  $this->user = $DIC['ilUser'];
82  $this->auth_session = $DIC['ilAuthSession'];
83  $this->lng = $DIC['lng'];
84  $this->settings = $DIC['ilSetting'];
85  $this->tpl = $DIC['tpl'];
86  $this->ctrl = $DIC['ilCtrl'];
87  $this->error_handler = $DIC['ilErr'];
88  $this->eventHandler = $DIC['ilAppEventHandler'];
89  $this->ui_factory = $DIC['ui.factory'];
90  $this->ui_renderer = $DIC['ui.renderer'];
91  $this->uploads = $DIC['upload'];
92  $this->irss = $DIC['resource_storage'];
93  $this->stakeholder = new ilUserProfilePictureStakeholder();
94 
95  $this->user_defined_fields = ilUserDefinedFields::_getInstance();
96 
97  $this->change_mail_token_repo = new ProfileChangeMailTokenDBRepository($DIC['ilDB']);
98 
99  $this->lng->loadLanguageModule('jsmath');
100  $this->lng->loadLanguageModule('pd');
101  $this->upload_error = '';
102  $this->password_error = '';
103  $this->lng->loadLanguageModule('user');
104  $this->ctrl->saveParameter($this, 'prompted');
105 
106  $this->checklist = new ilProfileChecklistGUI();
107  $this->checklist_status = new ilProfileChecklistStatus();
108 
109  $this->user_settings_config = new ilUserSettingsConfig();
110 
111  $this->ui_factory = $DIC['ui.factory'];
112  $this->ui_renderer = $DIC['ui.renderer'];
113  $this->auth_session = $DIC['ilAuthSession'];
114  $this->change_mail_token_repo = new ProfileChangeMailTokenDBRepository($DIC['ilDB']);
115 
116  $this->profile_request = new ProfileGUIRequest(
117  $DIC->http(),
118  $DIC->refinery()
119  );
120  }
121 
122  public function executeCommand(): void
123  {
124  $next_class = $this->ctrl->getNextClass();
125 
126  switch ($next_class) {
127  case 'ilpublicuserprofilegui':
128  $pub_profile_gui = new ilPublicUserProfileGUI($this->user->getId());
129  $pub_profile_gui->setBackUrl($this->ctrl->getLinkTarget($this, 'showPersonalData'));
130  $this->ctrl->forwardCommand($pub_profile_gui);
131  $this->tpl->printToStdout();
132  break;
133 
134  case 'iluserprivacysettingsgui':
135  $this->setHeader();
136  $this->setTabs();
137  $this->tabs->activateTab('visibility_settings');
139  $gui = new ilUserPrivacySettingsGUI();
140  $this->ctrl->forwardCommand($gui);
141  break;
142 
143  case strtolower(ilLegalDocumentsAgreementGUI::class):
144  $this->ctrl->forwardCommand(new ilLegalDocumentsAgreementGUI());
145  $this->tpl->printToStdout();
146  break;
147 
148  case strtolower(ilLegalDocumentsWithdrawalGUI::class):
149  $this->ctrl->forwardCommand(new ilLegalDocumentsWithdrawalGUI());
150  $this->tpl->printToStdout();
151  break;
152 
153  default:
154  $this->setTabs();
155  $cmd = $this->ctrl->getCmd('showPersonalData');
156  $this->$cmd();
157  break;
158  }
159  }
160 
161 
162  public function workWithUserSetting(string $setting): bool
163  {
164  return $this->user_settings_config->isVisibleAndChangeable($setting);
165  }
166 
167  public function userSettingVisible(string $setting): bool
168  {
169  return $this->user_settings_config->isVisible($setting);
170  }
171 
172  public function userSettingEnabled(string $setting): bool
173  {
174  return $this->user_settings_config->isChangeable($setting);
175  }
176 
177  public function uploadUserPicture(): void
178  {
179  if (!$this->workWithUserSetting('upload')) {
180  return;
181  }
182 
183  if (!$this->form->hasFileUpload('userfile')
184  && $this->profile_request->getUserFileCapture() === '') {
185  if ($this->form->getItemByPostVar('userfile')->getDeletionFlag()) {
186  $this->user->removeUserPicture();
187  }
188  return;
189  }
190 
191  // User has uploaded a file of a captured image
192  if (!$this->uploads->hasBeenProcessed()) {
193  $this->uploads->process();
194  }
195  $existing_rid = $this->irss->manage()->find($this->user->getAvatarRid());
196  $revision_title = 'Avatar for user ' . $this->user->getLogin();
197 
198  // move uploaded file
199  if ($this->form->hasFileUpload('userfile') && $this->uploads->hasBeenProcessed()) {
200  $stream = Streams::ofResource(
201  fopen(
202  $this->form->getFileUpload('userfile')['tmp_name'],
203  'r'
204  )
205  );
206 
207  if ($existing_rid === null) {
208  $rid = $this->irss->manage()->stream(
209  $stream,
210  $this->stakeholder,
211  $revision_title
212  );
213  } else {
214  $rid = $existing_rid;
215  $this->irss->manage()->replaceWithStream(
216  $existing_rid,
217  $stream,
218  $this->stakeholder,
219  $revision_title
220  );
221  }
222 
223  if (!isset($rid)) {
224  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('upload_error_file_not_found'), true);
225  $this->ctrl->redirect($this, 'showProfile');
226  }
227  $this->user->setAvatarRid($rid->serialize());
228  $this->irss->flavours()->ensure($rid, new ilUserProfilePictureDefinition()); // Create different sizes
229  $this->user->update();
230  return;
231  }
232 
233  $capture = $this->profile_request->getUserFileCapture();
234  if ($capture === null) {
235  return;
236  }
237 
238  $img = str_replace(
239  ['data:image/png;base64,', ' '],
240  ['', '+'],
241  $capture
242  );
243  $data = base64_decode($img);
244  if ($data === false) {
245  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('upload_error_file_not_found'), true);
246  $this->ctrl->redirect($this, 'showProfile');
247  }
248  $stream = Streams::ofString($data);
249 
250  if ($existing_rid === null) {
251  $rid = $this->irss->manage()->stream(
252  $stream,
253  $this->stakeholder,
254  $revision_title
255  );
256  } else {
257  $rid = $existing_rid;
258  $this->irss->manage()->replaceWithStream(
259  $rid,
260  $stream,
261  $this->stakeholder,
262  $revision_title
263  );
264  }
265  $this->user->setAvatarRid($rid->serialize());
266  $this->irss->flavours()->ensure($rid, new ilUserProfilePictureDefinition()); // Create different sizes
267  $this->user->update();
268  }
269 
270  public function removeUserPicture(): void
271  {
272  $this->user->removeUserPicture();
273  }
274 
280  public function showProfile(): void
281  {
282  $this->showPersonalData();
283  }
284 
288  public function addLocationToForm(ilPropertyFormGUI $a_form, ilObjUser $a_user): void
289  {
290  // check map activation
291  if (!ilMapUtil::isActivated()) {
292  return;
293  }
294 
295  // Don't really know if this is still necessary...
296  $this->lng->loadLanguageModule('maps');
297 
298  // Get user settings
299  $latitude = ($a_user->getLatitude() != '')
300  ? (float) $a_user->getLatitude()
301  : null;
302  $longitude = ($a_user->getLongitude() != '')
303  ? (float) $a_user->getLongitude()
304  : null;
305  $zoom = $a_user->getLocationZoom();
306 
307  // Get Default settings, when nothing is set
308  if ($latitude == null && $longitude == null && $zoom == 0) {
310  $latitude = (float) $def['latitude'];
311  $longitude = (float) $def['longitude'];
312  $zoom = (int) $def['zoom'];
313  }
314 
315  $street = $a_user->getStreet();
316  if (!$street) {
317  $street = $this->lng->txt('street');
318  }
319  $city = $a_user->getCity();
320  if (!$city) {
321  $city = $this->lng->txt('city');
322  }
323  $country = $a_user->getCountry();
324  if (!$country) {
325  $country = $this->lng->txt('country');
326  }
327 
328  // location property
329  $loc_prop = new ilLocationInputGUI(
330  $this->lng->txt('location'),
331  'location'
332  );
333  $loc_prop->setLatitude($latitude);
334  $loc_prop->setLongitude($longitude);
335  $loc_prop->setZoom($zoom);
336  $loc_prop->setAddress($street . ',' . $city . ',' . $country);
337 
338  $a_form->addItem($loc_prop);
339  }
340 
341  // init sub tabs
342  public function setTabs(): void
343  {
344  $this->help->setScreenIdComponent('user');
345 
346  // personal data
347  $this->tabs->addTab(
348  'personal_data',
349  $this->lng->txt('user_profile_data'),
350  $this->ctrl->getLinkTarget($this, 'showPersonalData')
351  );
352 
353  // publishing options
354  $this->tabs->addTab(
355  'public_profile',
356  $this->lng->txt('user_publish_options'),
357  $this->ctrl->getLinkTarget($this, 'showPublicProfile')
358  );
359 
360  // visibility settings
361  $txt_visibility = $this->checklist_status->anyVisibilitySettings()
362  ? $this->lng->txt('user_visibility_settings')
363  : $this->lng->txt('preview');
364  $this->tabs->addTab(
365  'visibility_settings',
366  $txt_visibility,
367  $this->ctrl->getLinkTargetByClass('ilUserPrivacySettingsGUI', '')
368  );
369 
370  // export
371  $this->tabs->addTab(
372  'export',
373  $this->lng->txt('export') . '/' . $this->lng->txt('import'),
374  $this->ctrl->getLinkTarget($this, 'showExportImport')
375  );
376  }
377 
378 
379  public function __showOtherInformations(): bool
380  {
381  $d_set = new ilSetting('delicous');
382  if ($this->userSettingVisible('matriculation') or count($this->user_defined_fields->getVisibleDefinitions())
383  or $d_set->get('user_profile') == '1') {
384  return true;
385  }
386  return false;
387  }
388 
389  public function __showUserDefinedFields(): bool
390  {
391  $user_defined_data = $this->user->getUserDefinedData();
392  foreach ($this->user_defined_fields->getVisibleDefinitions() as $field_id => $definition) {
393  if ($definition['field_type'] == UDF_TYPE_TEXT) {
394  $this->tpl->setCurrentBlock('field_text');
395  $this->tpl->setVariable(
396  'FIELD_VALUE',
397  ilLegacyFormElementsUtil::prepareFormOutput($user_defined_data[$field_id])
398  );
399  if (!$definition['changeable']) {
400  $this->tpl->setVariable('DISABLED_FIELD', 'disabled="disabled"');
401  }
402  $this->tpl->setVariable('FIELD_NAME', 'udf[' . $definition['field_id'] . ']');
403  } else {
404  if ($definition['changeable']) {
405  $name = 'udf[' . $definition['field_id'] . ']';
406  $disabled = false;
407  } else {
408  $name = '';
409  $disabled = true;
410  }
411  $this->tpl->setCurrentBlock('field_select');
412  $this->tpl->setVariable(
413  'SELECT_BOX',
415  $user_defined_data[$field_id],
416  $name,
417  $this->user_defined_fields->fieldValuesToSelectArray(
418  $definition['field_values']
419  ),
420  false,
421  true,
422  0,
423  '',
424  [],
425  $disabled
426  )
427  );
428  }
429  $this->tpl->parseCurrentBlock();
430  $this->tpl->setCurrentBlock('user_defined');
431 
432  if ($definition['required']) {
433  $name = $definition['field_name'] . '<span class="asterisk">*</span>';
434  } else {
435  $name = $definition['field_name'];
436  }
437  $this->tpl->setVariable('TXT_FIELD_NAME', $name);
438  $this->tpl->parseCurrentBlock();
439  }
440  return true;
441  }
442 
443  public function setHeader(): void
444  {
445  $this->tpl->setTitle($this->lng->txt('personal_profile'));
446  }
447 
448  public function showPersonalData(
449  bool $a_no_init = false
450  ): void {
451  $prompt_service = new ilUserProfilePromptService();
452 
453  $this->tabs->activateTab('personal_data');
454 
455  $it = '';
456  if ($this->profile_request->getPrompted() == 1) {
457  $it = $prompt_service->data()->getSettings()->getPromptText($this->user->getLanguage());
458  }
459  if ($it === '') {
460  $it = $prompt_service->data()->getSettings()->getInfoText($this->user->getLanguage());
461  }
462  if (trim($it) !== '') {
463  $pub_prof = in_array($this->user->prefs['public_profile'] ?? '', ['y', 'n', 'g'])
464  ? $this->user->prefs['public_profile']
465  : 'n';
466  $box = $this->ui_factory->messageBox()->info($it);
467  if ($pub_prof === 'n') {
468  $box = $box->withLinks(
469  [$this->ui_factory->link()->standard(
470  $this->lng->txt('user_make_profile_public'),
471  $this->ctrl->getLinkTarget($this, 'showPublicProfile')
472  )]
473  );
474  }
475  $it = $this->ui_renderer->render($box);
476  }
477  $this->setHeader();
478 
480 
481  if (!$a_no_init) {
482  $this->initPersonalDataForm();
483  // catch feedback message
484  if ($this->user->getProfileIncomplete()) {
485  $this->tpl->setOnScreenMessage('info', $this->lng->txt('profile_incomplete'));
486  }
487  }
488 
489  $modal = '';
490  if ($this->email_change_confirmation_modal !== null) {
491  $modal = $this->ui_renderer->render($this->email_change_confirmation_modal);
492  }
493 
494  $this->tpl->setContent($it . $this->form->getHTML() . $modal);
495 
496  $this->tpl->printToStdout();
497  }
498 
499  public function initPersonalDataForm(): void
500  {
501  $input = [];
502 
503  $this->form = new ilPropertyFormGUI();
504  $this->form->setFormAction($this->ctrl->getFormAction($this));
505  $this->form->setId(self::PERSONAL_DATA_FORM_ID);
506 
507  // user defined fields
508  $user_defined_data = $this->user->getUserDefinedData();
509 
510  foreach ($this->user_defined_fields->getVisibleDefinitions() as $field_id => $definition) {
511  $value = $user_defined_data['f_' . $field_id] ?? '';
512  $changeable = $definition['changeable'] === 1 ? true : false;
513  $fprop = ilCustomUserFieldsHelper::getInstance()->getFormPropertyForDefinition(
514  $definition,
515  $changeable,
516  $value
517  );
518  if ($fprop instanceof ilFormPropertyGUI) {
519  $input['udf_' . $definition['field_id']] = $fprop;
520  }
521  }
522 
523  // standard fields
524  $up = new ilUserProfile();
525  $up->skipField('password');
526  $up->skipGroup('settings');
527  $up->skipGroup('preferences');
528 
529  $up->setAjaxCallback(
530  $this->ctrl->getLinkTargetByClass('ilPublicUserProfileGUI', 'doProfileAutoComplete', '', true)
531  );
532 
533  // standard fields
534  $up->addStandardFieldsToForm($this->form, $this->user, $input);
535 
536  $this->addLocationToForm($this->form, $this->user);
537 
538  $this->form->addCommandButton('savePersonalData', $this->lng->txt('user_save_continue'));
539  }
540 
541  public function savePersonalData(): void
542  {
543  $this->initPersonalDataForm();
544 
545  $this->uploads->process();
546 
547  if (!$this->form->checkInput()
548  || !$this->emailCompletionForced()
549  && $this->emailChanged()
550  && $this->addEmailChangeModal()
551  || $this->loginChanged() && !$this->updateLoginOrSetErrorMessages()) {
552  $this->form->setValuesByPost();
553  $this->tempStorePicture();
554  $this->showPersonalData(true);
555  return;
556  }
557 
558  $this->savePersonalDataForm();
559 
560  $this->checklist_status->saveStepSucess(ilProfileChecklistStatus::STEP_PROFILE_DATA);
561  $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_obj_modified'), true);
562 
563  $this->ctrl->redirect($this, 'showPublicProfile');
564  }
565 
566  private function emailChanged(): bool
567  {
568  $email_input = $this->form->getItemByPostVar('usr_email');
569  if ($email_input !== null && !$email_input->getDisabled()
570  && $this->form->getInput('usr_email') !== $this->user->getEmail()) {
571  return true;
572  }
573 
574  return false;
575  }
576 
577  private function emailCompletionForced(): bool
578  {
579  $current_email = $this->user->getEmail();
580  if (
581  $this->user->getProfileIncomplete()
582  && $this->settings->get('require_email') === '1'
583  && ($current_email === null || $current_email === '')
584  ) {
585  return true;
586  }
587 
588  return false;
589  }
590 
591  private function addEmailChangeModal(): bool
592  {
593  $form_id = 'form_' . self::PERSONAL_DATA_FORM_ID;
594  $modal = $this->ui_factory->modal()->interruptive(
595  $this->lng->txt('confirm'),
596  $this->lng->txt('confirm_logout_for_email_change'),
597  '#'
598  )->withActionButtonLabel($this->lng->txt('change'));
599  $this->email_change_confirmation_modal = $modal->withOnLoad($modal->getShowSignal())
601  static function ($id) use ($form_id) {
602  return "var button = {$id}.querySelector('input[type=\"submit\"]'); "
603  . "button.addEventListener('click', (e) => {e.preventDefault();"
604  . "document.getElementById('{$form_id}').submit();});";
605  }
606  );
607 
608  $this->form->setFormAction($this->ctrl->getFormActionByClass(self::class, 'goToEmailConfirmation'));
609  return true;
610  }
611 
612  private function loginChanged(): bool
613  {
614  $login = $this->form->getInput('username');
615  if ((int) $this->settings->get('allow_change_loginname')
616  && $login !== $this->user->getLogin()) {
617  return true;
618  }
619 
620  return false;
621  }
622 
623  private function updateLoginOrSetErrorMessages(): bool
624  {
625  $login = $this->form->getInput('username');
626  if ($login === '' || !ilUtil::isLogin($login)) {
627  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('form_input_not_valid'));
628  $this->form->getItemByPostVar('username')->setAlert($this->lng->txt('login_invalid'));
629  return false;
630  }
631 
632  if (ilObjUser::_loginExists($login, $this->user->getId())) {
633  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('form_input_not_valid'));
634  $this->form->getItemByPostVar('username')->setAlert($this->lng->txt('loginname_already_exists'));
635  return false;
636  }
637 
638  $this->user->setLogin($login);
639 
640  try {
641  $this->user->updateLogin($this->user->getLogin());
642  return true;
643  } catch (ilUserException $e) {
644  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('form_input_not_valid'));
645  $this->form->getItemByPostVar('username')->setAlert($e->getMessage());
646  return false;
647  }
648  }
649 
650  public function goToEmailConfirmation(): void
651  {
652  $this->initPersonalDataForm();
653  if (!$this->form->checkInput()
654  || $this->loginChanged() && !$this->updateLoginOrSetErrorMessages()) {
655  $this->form->setValuesByPost();
656  $this->showPersonalData(true);
657  return;
658  }
659  $this->savePersonalDataForm();
660 
662  $this->auth_session->logout();
663  session_unset();
664  $token = $this->change_mail_token_repo->getNewTokenForUser($this->user, $this->form->getInput('usr_email'));
665  $this->ctrl->redirectToURL('login.php?cmd=force_login&target=usr_' . self::CHANGE_EMAIL_CMD . $token);
666  }
667 
668  private function savePersonalDataForm(): void
669  {
670  // if form field name differs from setter
671  $map = [
672  'firstname' => 'FirstName',
673  'lastname' => 'LastName',
674  'title' => 'UTitle',
675  'sel_country' => 'SelectedCountry',
676  'phone_office' => 'PhoneOffice',
677  'phone_home' => 'PhoneHome',
678  'phone_mobile' => 'PhoneMobile',
679  'referral_comment' => 'Comment',
680  'interests_general' => 'GeneralInterests',
681  'interests_help_offered' => 'OfferingHelp',
682  'interests_help_looking' => 'LookingForHelp'
683  ];
684  $up = new ilUserProfile();
685  foreach ($up->getStandardFields() as $f => $p) {
686  // if item is part of form, it is currently valid (if not disabled)
687  $item = $this->form->getItemByPostVar('usr_' . $f);
688  if ($item && !$item->getDisabled()) {
689  $value = $this->form->getInput('usr_' . $f);
690  switch ($f) {
691  case 'email':
692  if ($this->emailCompletionForced()) {
693  $this->user->setEmail($value);
694  }
695  break;
696  case 'birthday':
697  $value = $item->getDate();
698  $this->user->setBirthday($value
699  ? $value->get(IL_CAL_DATE)
700  : '');
701  break;
702  case 'second_email':
703  $this->user->setSecondEmail($value);
704  break;
705  default:
706  $m = $map[$f] ?? ucfirst($f);
707  $this->user->{'set' . $m}($value);
708  break;
709  }
710  }
711  }
712  $this->user->setFullname();
713 
714  // check map activation
715  if (ilMapUtil::isActivated()) {
716  // #17619 - proper escaping
717  $location = $this->form->getInput('location');
718  $this->user->setLatitude(is_numeric($location['latitude']) ? (string) $location['latitude'] : null);
719  $this->user->setLongitude(is_numeric($location['longitude']) ? (string) $location['longitude'] : null);
720  $this->user->setLocationZoom(is_numeric($location['zoom']) ? $location['zoom'] : null);
721  }
722 
723  // Set user defined data
724  $defs = $this->user_defined_fields->getVisibleDefinitions();
725  $udf = [];
726  foreach ($defs as $definition) {
727  $f = 'udf_' . $definition['field_id'];
728  $item = $this->form->getItemByPostVar($f);
729  if ($item && !$item->getDisabled()) {
730  $udf[$definition['field_id']] = $this->form->getInput($f);
731  }
732  }
733  $this->user->setUserDefinedData($udf);
734 
735  $this->uploadUserPicture();
736 
737  // profile ok
738  $this->user->setProfileIncomplete(false);
739 
740  // save user data & object_data
741  $this->user->setTitle($this->user->getFullname());
742  $this->user->setDescription($this->user->getEmail());
743 
744  $this->user->update();
745  }
746 
747  public function changeEmail(): void
748  {
749  $token = $this->profile_request->getToken();
750  $new_email = $this->change_mail_token_repo->getNewEmailForUser($this->user, $token);
751 
752  if ($new_email !== '') {
753  $this->user->setEmail($new_email);
754  $this->user->update();
755  $this->change_mail_token_repo->deleteEntryByToken($token);
756  $this->tpl->setOnScreenMessage(
757  'success',
758  $this->lng->txt('saved_successfully')
759  );
760  $this->showPublicProfile();
761  return;
762  }
763 
764  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('email_could_not_be_changed'));
765  $this->showPublicProfile();
766  }
767 
768  public function showPublicProfile(bool $a_no_init = false): void
769  {
770  $this->tabs->activateTab('public_profile');
772 
773  $this->setHeader();
774 
775  if (!$a_no_init) {
776  $this->initPublicProfileForm();
777  }
778 
779  $this->tpl->setContent($this->form->getHTML());
780  $this->tpl->printToStdout();
781  }
782 
783  protected function getProfilePortfolio(): ?int
784  {
785  if ($this->settings->get('user_portfolios')) {
786  return ilObjPortfolio::getDefaultPortfolio($this->user->getId());
787  }
788  return null;
789  }
790 
791  public function initPublicProfileForm(): void
792  {
793  $this->form = new ilPropertyFormGUI();
794 
795  $this->form->setTitle($this->lng->txt('user_publish_options'));
796  $this->form->setDescription($this->lng->txt('user_public_profile_info'));
797  $this->form->setFormAction($this->ctrl->getFormAction($this));
798 
799  $portfolio_id = $this->getProfilePortfolio();
800 
801  if (!$portfolio_id) {
802  // Activate public profile
803  $radg = new ilRadioGroupInputGUI($this->lng->txt('user_activate_public_profile'), 'public_profile');
804  $info = $this->lng->txt('user_activate_public_profile_info');
805  $profile_mode = new ilPersonalProfileMode($this->user, $this->settings);
806  $pub_prof = $profile_mode->getMode();
807  $radg->setValue($pub_prof);
808  $op1 = new ilRadioOption($this->lng->txt('usr_public_profile_disabled'), 'n', $this->lng->txt('usr_public_profile_disabled_info'));
809  $radg->addOption($op1);
810  $op2 = new ilRadioOption($this->lng->txt('usr_public_profile_logged_in'), 'y');
811  $radg->addOption($op2);
812  if ($this->settings->get('enable_global_profiles')) {
813  $op3 = new ilRadioOption($this->lng->txt('usr_public_profile_global'), 'g');
814  $radg->addOption($op3);
815  }
816  $this->form->addItem($radg);
817 
818  // #11773
819  if ($this->settings->get('user_portfolios')) {
820  // #10826
821  $href = $this->ctrl->getLinkTargetByClass(ilDashboardGUI::class, 'jumpToPortfolio');
822  $prtf = '<br />' . $this->lng->txt('user_profile_portfolio');
823  $prtf .= '<br /><a href="' . $href . '">&raquo; ' .
824  $this->lng->txt('user_portfolios') . '</a>';
825  $info .= $prtf;
826  }
827 
828  $radg->setInfo($info);
829  } else {
830  $this->ctrl->setParameterByClass(ilDashboardGUI::class, 'prt_id', $portfolio_id);
831  $href = $this->ctrl->getLinkTargetByClass(ilDashboardGUI::class, 'jumpToPortfolio');
832  $this->ctrl->clearParameterByClass(ilDashboardGUI::class, 'prt_id');
833  $prtf = $this->lng->txt('user_profile_portfolio_selected');
834  $prtf .= '<br /><a href="' . $href . '">&raquo; ' .
835  $this->lng->txt('portfolio') . '</a>';
836 
837  $info = new ilCustomInputGUI($this->lng->txt('user_activate_public_profile'));
838  $info->setHtml($prtf);
839  $this->form->addItem($info);
840  $this->showPublicProfileFields($this->form, $this->user->prefs);
841  }
842 
843  if (isset($op2)) {
844  $this->showPublicProfileFields($this->form, $this->user->prefs, $op2, false, '-1');
845  }
846  if (isset($op3)) {
847  $this->showPublicProfileFields($this->form, $this->user->prefs, $op3, false, '-2');
848  }
849  $this->form->setForceTopButtons(true);
850  $this->form->addCommandButton('savePublicProfile', $this->lng->txt('user_save_continue'));
851  }
852 
853  public function showPublicProfileFields(
855  array $prefs,
856  ?object $parent = null,
857  bool $anonymized = false,
858  string $key_suffix = ''
859  ): void {
860  $birthday = $this->user->getBirthday();
861  if ($birthday) {
862  $birthday = ilDatePresentation::formatDate(new ilDate($birthday, IL_CAL_DATE));
863  }
864  $gender = $this->user->getGender();
865  if ($gender) {
866  $gender = $this->lng->txt('gender_' . $gender);
867  }
868 
869  $txt_sel_country = '';
870  if ($this->user->getSelectedCountry() != '') {
871  $this->lng->loadLanguageModule('meta');
872  $txt_sel_country = $this->lng->txt('meta_c_' . $this->user->getSelectedCountry());
873  }
874 
875  // profile picture
876  $pic = ilObjUser::_getPersonalPicturePath($this->user->getId(), 'xsmall', true, true);
877  if ($pic) {
878  $pic = "<img src='{$pic}' alt='{$this->lng->txt('user_avatar')}' />";
879  }
880 
881  // personal data
882  $val_array = [
883  'title' => $this->user->getUTitle(),
884  'birthday' => $birthday,
885  'gender' => $gender,
886  'upload' => $pic,
887  'interests_general' => $this->user->getGeneralInterestsAsText(),
888  'interests_help_offered' => $this->user->getOfferingHelpAsText(),
889  'interests_help_looking' => $this->user->getLookingForHelpAsText(),
890  'org_units' => $this->user->getOrgUnitsRepresentation(),
891  'institution' => $this->user->getInstitution(),
892  'department' => $this->user->getDepartment(),
893  'street' => $this->user->getStreet(),
894  'zipcode' => $this->user->getZipcode(),
895  'city' => $this->user->getCity(),
896  'country' => $this->user->getCountry(),
897  'sel_country' => $txt_sel_country,
898  'phone_office' => $this->user->getPhoneOffice(),
899  'phone_home' => $this->user->getPhoneHome(),
900  'phone_mobile' => $this->user->getPhoneMobile(),
901  'fax' => $this->user->getFax(),
902  'email' => $this->user->getEmail(),
903  'second_email' => $this->user->getSecondEmail(),
904  'hobby' => $this->user->getHobby(),
905  'matriculation' => $this->user->getMatriculation()
906  ];
907 
908  // location
909  if (ilMapUtil::isActivated()) {
910  $val_array['location'] = ((int) $this->user->getLatitude() +
911  (int) $this->user->getLongitude()
912  + (int) $this->user->getLocationZoom() > 0)
913  ? ' '
914  : '';
915  }
916  foreach ($val_array as $key => $value) {
917  if (in_array($value, ['', '-']) && !$anonymized) {
918  continue;
919  }
920  if ($anonymized) {
921  $value = null;
922  }
923 
924  if ($this->userSettingVisible($key)) {
925  // #18795 - we should use ilUserProfile
926  switch ($key) {
927  case 'upload':
928  $caption = 'personal_picture';
929  break;
930 
931  case 'title':
932  $caption = 'person_title';
933  break;
934 
935  default:
936  $caption = $key;
937  }
938  $cb = new ilCheckboxInputGUI($this->lng->txt($caption), 'chk_' . $key . $key_suffix);
939  if (isset($prefs['public_' . $key]) && $prefs['public_' . $key] == 'y') {
940  $cb->setChecked(true);
941  }
942  $cb->setOptionTitle((string) $value);
943 
944  if (!$parent) {
945  $form->addItem($cb);
946  } else {
947  $parent->addSubItem($cb);
948  }
949  }
950  }
951 
952  // additional defined user data fields
953  $user_defined_data = [];
954  if (!$anonymized) {
955  $user_defined_data = $this->user->getUserDefinedData();
956  }
957  foreach ($this->user_defined_fields->getVisibleDefinitions() as $field_id => $definition) {
958  // public setting
959  $cb = new ilCheckboxInputGUI($definition['field_name'], 'chk_udf_' . $definition['field_id'] . $key_suffix);
960  $cb->setOptionTitle($user_defined_data['f_' . $definition['field_id']] ?? '');
961  $public_udf = (string) ($prefs['public_udf_' . $definition['field_id']] ?? '');
962  if ($public_udf === 'y') {
963  $cb->setChecked(true);
964  }
965 
966  if (!$parent) {
967  $form->addItem($cb);
968  } else {
969  $parent->addSubItem($cb);
970  }
971  }
972 
973  if (!$anonymized) {
975  if ($handler->isActive()) {
976  $badge_options = [];
977 
978  foreach (ilBadgeAssignment::getInstancesByUserId($this->user->getId()) as $ass) {
979  // only active
980  if ($ass->getPosition()) {
981  $badge = new ilBadge($ass->getBadgeId());
982  $badge_options[] = $badge->getTitle();
983  }
984  }
985 
986  if (count($badge_options) > 1) {
987  $badge_order = new ilNonEditableValueGUI($this->lng->txt('obj_bdga'), 'bpos' . $key_suffix);
988  $badge_order->setMultiValues($badge_options);
989  $badge_order->setValue(array_shift($badge_options));
990  $badge_order->setMulti(true, true, false);
991 
992  if (!$parent) {
993  $form->addItem($badge_order);
994  } else {
995  $parent->addSubItem($badge_order);
996  }
997  }
998  }
999  }
1000 
1001  // permalink
1002  $ne = new ilNonEditableValueGUI($this->lng->txt('perma_link'), '');
1003  $ne->setValue(ilLink::_getLink($this->user->getId(), 'usr'));
1004  if (!$parent) {
1005  $form->addItem($ne);
1006  } else {
1007  $parent->addSubItem($ne);
1008  }
1009  }
1010 
1011  public function savePublicProfile(): void
1012  {
1013  $key_suffix = '';
1014 
1015  $this->initPublicProfileForm();
1016  if ($this->form->checkInput()) {
1017  // with active portfolio no options are presented
1018  if ($this->form->getInput('public_profile') != '') {
1019  $this->user->setPref('public_profile', $this->form->getInput('public_profile'));
1020  }
1021 
1022  // if check on Institute
1023  $val_array = ['title', 'birthday', 'gender', 'org_units',
1024  'institution', 'department', 'upload', 'street', 'zipcode',
1025  'city', 'country', 'sel_country', 'phone_office', 'phone_home',
1026  'phone_mobile', 'fax', 'email', 'second_email', 'hobby',
1027  'matriculation', 'location', 'interests_general',
1028  'interests_help_offered', 'interests_help_looking'];
1029 
1030  // set public profile preferences
1031  $checked_values = $this->getCheckedValues();
1032  foreach ($val_array as $key => $value) {
1033  if ($checked_values['chk_' . $value] ?? false) {
1034  $this->user->setPref('public_' . $value, 'y');
1035  } else {
1036  $this->user->setPref('public_' . $value, 'n');
1037  }
1038  }
1039  // additional defined user data fields
1040  foreach ($this->user_defined_fields->getVisibleDefinitions() as $field_id => $definition) {
1041  if ($checked_values['chk_udf_' . $definition['field_id']] ?? false) {
1042  $this->user->setPref('public_udf_' . $definition['field_id'], 'y');
1043  } else {
1044  $this->user->setPref('public_udf_' . $definition['field_id'], 'n');
1045  }
1046  }
1047 
1048  $this->user->update();
1049 
1050  switch ($this->form->getInput('public_profile')) {
1051  case 'y':
1052  $key_suffix = '-1';
1053  break;
1054  case 'g':
1055  $key_suffix = '-2';
1056  break;
1057  }
1058 
1060  if ($handler->isActive()) {
1061  $badgePositions = [];
1062  $bpos = $this->form->getInput('bpos' . $key_suffix);
1063  if (isset($bpos) && is_array($bpos)) {
1064  $badgePositions = $bpos;
1065  }
1066 
1067  if (count($badgePositions) > 0) {
1068  ilBadgeAssignment::updatePositions($this->user->getId(), $badgePositions);
1069  }
1070  }
1071 
1072  // update lucene index
1073  ilLuceneIndexer::updateLuceneIndex([(int) $this->user->getId()]);
1074 
1075  $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_obj_modified'), true);
1076 
1077  $this->checklist_status->saveStepSucess(ilProfileChecklistStatus::STEP_PUBLISH_OPTIONS);
1078 
1079  if (ilSession::get('orig_request_target')) {
1080  $target = ilSession::get('orig_request_target');
1081  ilSession::set('orig_request_target', '');
1082  ilUtil::redirect($target);
1083  } else {
1084  $this->ctrl->redirectByClass('iluserprivacysettingsgui', '');
1085  }
1086  }
1087  $this->form->setValuesByPost();
1088  $this->tpl->showPublicProfile(true);
1089  }
1090 
1091  protected function getCheckedValues(): array
1092  {
1093  $key_suffix = '';
1094  switch ($this->form->getInput('public_profile')) {
1095  case 'y':
1096  $key_suffix = '-1';
1097  break;
1098  case 'g':
1099  $key_suffix = '-2';
1100  break;
1101  }
1102 
1103  $checked_values = [];
1104  $post = $this->profile_request->getParsedBody();
1105  foreach ($post as $k => $v) {
1106  if (strpos($k, 'chk_') !== 0) {
1107  continue;
1108  }
1109  if (substr($k, -2) === $key_suffix) {
1110  $k = str_replace(['-1', '-2'], '', $k);
1111  }
1112  $checked_values[$k] = $v;
1113  }
1114  foreach ($this->user_defined_fields->getVisibleDefinitions() as $field_id => $definition) {
1115  if (isset($post['chk_udf_' . $definition['field_id'] . $key_suffix])) {
1116  $checked_values['chk_udf_' . $definition['field_id']] = '1';
1117  }
1118  }
1119  return $checked_values;
1120  }
1121 
1122  public function showExportImport(): void
1123  {
1124  $this->tabs->activateTab('export');
1125  $this->setHeader();
1126 
1127  $button = $this->ui_factory->link()->standard(
1128  $this->lng->txt('pd_export_profile'),
1129  $this->ctrl->getLinkTarget($this, 'exportPersonalData')
1130  );
1131  $this->toolbar->addStickyItem($button);
1132 
1133  $exp_file = $this->user->getPersonalDataExportFile();
1134  if ($exp_file != '') {
1135  $this->toolbar->addSeparator();
1136  $this->toolbar->addComponent(
1137  $this->ui_factory->link()->standard(
1138  $this->lng->txt("pd_download_last_export_file"),
1139  $this->ctrl->getLinkTarget($this, "downloadPersonalData")
1140  )
1141  );
1142  }
1143 
1144  $this->toolbar->addSeparator();
1145  $this->toolbar->addComponent(
1146  $this->ui_factory->link()->standard(
1147  $this->lng->txt("pd_import_personal_data"),
1148  $this->ctrl->getLinkTarget($this, "importPersonalDataSelection")
1149  )
1150  );
1151 
1152  $this->tpl->printToStdout();
1153  }
1154 
1155  public function exportPersonalData(): void
1156  {
1157  $this->user->exportPersonalData();
1158  $this->user->sendPersonalDataFile();
1159  $this->ctrl->redirect($this, 'showExportImport');
1160  }
1161 
1165  public function downloadPersonalData(): void
1166  {
1167  $this->user->sendPersonalDataFile();
1168  }
1169 
1170  public function importPersonalDataSelection(): void
1171  {
1172  $this->tabs->activateTab('export');
1173  $this->setHeader();
1174 
1175  $this->initPersonalDataImportForm();
1176 
1177  $this->tpl->setContent($this->form->getHTML());
1178  $this->tpl->printToStdout();
1179  }
1180 
1181  public function initPersonalDataImportForm(): void
1182  {
1183  $this->form = new ilPropertyFormGUI();
1184 
1185  // input file
1186  $fi = new ilFileInputGUI($this->lng->txt('file'), 'file');
1187  $fi->setRequired(true);
1188  $fi->setSuffixes(['zip']);
1189  $this->form->addItem($fi);
1190 
1191  // profile data
1192  $cb = new ilCheckboxInputGUI($this->lng->txt('pd_profile_data'), 'profile_data');
1193  $this->form->addItem($cb);
1194 
1195  // settings
1196  $cb = new ilCheckboxInputGUI($this->lng->txt('settings'), 'settings');
1197  $this->form->addItem($cb);
1198 
1199  // personal notes
1200  $cb = new ilCheckboxInputGUI($this->lng->txt('notes'), 'notes');
1201  $this->form->addItem($cb);
1202 
1203  // calendar entries
1204  $cb = new ilCheckboxInputGUI($this->lng->txt('pd_private_calendars'), 'calendar');
1205  $this->form->addItem($cb);
1206 
1207  $this->form->addCommandButton('importPersonalData', $this->lng->txt('import'));
1208  $this->form->addCommandButton('showExportImport', $this->lng->txt('cancel'));
1209 
1210  $this->form->setTitle($this->lng->txt('pd_import_personal_data'));
1211  $this->form->setFormAction($this->ctrl->getFormAction($this));
1212  }
1213 
1214  public function importPersonalData(): void
1215  {
1216  $this->initPersonalDataImportForm();
1217  if ($this->form->checkInput()) {
1218  $this->user->importPersonalData(
1219  $_FILES['file'],
1220  (bool) $this->form->getInput('profile_data'),
1221  (bool) $this->form->getInput('settings'),
1222  (bool) $this->form->getInput('notes'),
1223  (bool) $this->form->getInput('calendar')
1224  );
1225  $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_obj_modified'), true);
1226  $this->ctrl->redirect($this, '');
1227  } else {
1228  $this->tabs->activateTab('export');
1229  $this->setHeader();
1230  $this->form->setValuesByPost();
1231  $this->tpl->setContent($this->form->getHTML());
1232  $this->tpl->printToStdout();
1233  }
1234  }
1235 
1236  protected function showChecklist(int $active_step): void
1237  {
1238  $main_tpl = $this->tpl;
1239  $main_tpl->setRightContent($this->checklist->render($active_step));
1240  }
1241 
1242  private function tempStorePicture(): void
1243  {
1244  $capture = $this->profile_request->getUserFileCapture();
1245 
1246  if ($capture !== '') {
1247  $this->form->getItemByPostVar('userfile')->setImage($capture);
1248  $hidden_user_picture_carry = new ilHiddenInputGUI('user_picture_carry');
1249  $hidden_user_picture_carry->setValue($capture);
1250  $this->form->addItem($hidden_user_picture_carry);
1251  }
1252  }
1253 }
ilUserDefinedFields $user_defined_fields
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static get(string $a_var)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Global event handler.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ilProfileChecklistGUI $checklist
static updateLuceneIndex(array $a_obj_ids)
Update lucene index.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$location
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: buildRTE.php:22
static getInstancesByUserId(int $a_user_id)
Additional user data fields definition.
This class represents a file property in a property form.
Help GUI class.
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
static getDefaultPortfolio(int $a_user_id)
Get default portfolio of user.
Class ilUserProfile.
static formSelect( $selected, string $varname, array $options, bool $multiple=false, bool $direct_text=false, int $size=0, string $style_class="", array $attribs=[], bool $disabled=false)
Builds a select form field with options and shows the selected option first.
ResourceStakeholder $stakeholder
ProfileChangeMailTokenRepository $change_mail_token_repo
showPublicProfile(bool $a_no_init=false)
static prepareFormOutput($a_str, bool $a_strip=false)
setBackUrl(string $backurl)
Set Back Link URL.
ilUserSettingsConfig $user_settings_config
global $DIC
Definition: feed.php:28
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
GUI class for public user profile presentation.
This class represents a property in a property form.
__construct(VocabulariesInterface $vocabularies)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static updatePositions(int $a_user_id, array $a_positions)
downloadPersonalData()
Download personal data export file.
$token
Definition: xapitoken.php:70
const SESSION_CLOSE_USER
static _loginExists(string $a_login, int $a_user_id=0)
check if a login name already exists You may exclude a user from the check by giving his user id as 2...
static isLogin(string $a_login)
static getDefaultSettings()
Get default longitude, latitude and zoom.
This class represents a location property in a property form.
const UDF_TYPE_TEXT
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
string $key
Consumer key/client ID value.
Definition: System.php:193
Class FileUpload.
Definition: FileUpload.php:34
setRequired(bool $a_required)
static redirect(string $a_script)
static _getPersonalPicturePath(int $a_usr_id, string $a_size="small", bool $a_force_pic=false, bool $a_prevent_no_photo_image=false, bool $html_export=false)
showPersonalData(bool $a_no_init=false)
static isActivated()
Checks whether Map feature is activated.
form( $class_path, string $cmd, string $submit_caption="")
const IL_CAL_DATE
Error Handling & global info handling.
ilGlobalTemplateInterface $tpl
setLatitude(?float $a_latitude)
static setClosingContext(int $a_context)
set closing context (for statistics)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addLocationToForm(ilPropertyFormGUI $a_form, ilObjUser $a_user)
Add location fields to form if activated.
setRightContent(string $a_html)
Sets content of right column.
showPublicProfileFields(ilPropertyFormGUI $form, array $prefs, ?object $parent=null, bool $anonymized=false, string $key_suffix='')
$post
Definition: ltitoken.php:49
ilProfileChecklistStatus $checklist_status
static set(string $a_var, $a_val)
Set a value.
$handler
Definition: index.php:18