ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilSurveyParticipantsGUI.php
Go to the documentation of this file.
1 <?php
2 
21 
28 {
29  protected \ILIAS\Survey\InternalGUIService $gui;
30  protected \ILIAS\Survey\Mode\FeatureConfig $feature_config;
31  protected \ILIAS\Survey\Editing\EditingGUIRequest $edit_request;
32  protected \ILIAS\Survey\Editing\EditManager $edit_manager;
33  protected ilCtrl $ctrl;
34  protected ilLanguage $lng;
36  protected ilTabsGUI $tabs;
40  protected ilObjUser $user;
41  protected ilLogger $log;
43  protected ilObjSurvey $object;
44  protected int $ref_id;
45  protected bool $has_write;
46  protected Participants\InvitationsManager $invitation_manager;
47  protected \ILIAS\Survey\InternalService $survey_service;
48  protected \ILIAS\Survey\Code\CodeManager $code_manager;
49  protected \ILIAS\Survey\InternalDataService $data_manager;
50 
51  public function __construct(
52  ilObjSurveyGUI $a_parent_gui,
53  bool $a_has_write_access
54  ) {
55  global $DIC;
56 
57  $this->survey_service = $DIC->survey()->internal();
58 
59  $this->tabs = $DIC->tabs();
60  $this->toolbar = $DIC->toolbar();
61  $this->access = $DIC->access();
62  $this->rbacsystem = $DIC->rbac()->system();
63  $this->user = $DIC->user();
64  $this->log = $DIC["ilLog"];
65  $ilCtrl = $DIC->ctrl();
66  $lng = $DIC->language();
67  $tpl = $DIC["tpl"];
68 
69  $this->parent_gui = $a_parent_gui;
71  $survey = $this->parent_gui->getObject();
72  $this->object = $survey;
73  $this->ref_id = $this->object->getRefId();
74  $this->has_write = $a_has_write_access;
75 
76  $this->ctrl = $ilCtrl;
77  $this->lng = $lng;
78  $this->tpl = $tpl;
79  $this->invitation_manager = $this
80  ->survey_service
81  ->domain()
82  ->participants()
83  ->invitations();
84  $this->code_manager = $this
85  ->survey_service
86  ->domain()
87  ->code($this->object, $this->user->getId());
88  $this->data_manager = $this
89  ->survey_service
90  ->data();
91  $this->feature_config = $this
92  ->survey_service
93  ->domain()->modeFeatureConfig($this->object->getMode());
94  $this->edit_manager = $this->survey_service
95  ->domain()
96  ->edit();
97  $this->edit_request = $this->survey_service
98  ->gui()
99  ->editing()
100  ->request();
101  $this->gui = $this->survey_service->gui();
102  }
103 
104  public function getObject(): ilObjSurvey
105  {
106  return $this->object;
107  }
108 
109  protected function handleWriteAccess(): void
110  {
111  if (!$this->has_write) {
112  throw new ilSurveyException("Permission denied");
113  }
114  }
115 
116  public function executeCommand(): void
117  {
118  $ilCtrl = $this->ctrl;
119  $ilTabs = $this->tabs;
120  $lng = $this->lng;
121 
122  $cmd = $ilCtrl->getCmd("maintenance");
123  $next_class = $this->ctrl->getNextClass($this);
124 
125  switch ($next_class) {
126  case 'ilrepositorysearchgui':
127  $rep_search = new ilRepositorySearchGUI();
128 
129  if (!$this->edit_request->getAppr360() && !$this->edit_request->getRate360()) {
130  $ilTabs->clearTargets();
131  $ilTabs->setBackTarget(
132  $this->lng->txt("btn_back"),
133  $this->ctrl->getLinkTarget($this, "maintenance")
134  );
135 
136  $rep_search->setCallback(
137  $this,
138  'inviteUsers',
139  array(
140  )
141  );
142  $rep_search->setTitle($lng->txt("svy_invite_participants"));
143  // Set tabs
144  $this->ctrl->setReturn($this, 'maintenance');
145  $this->ctrl->forwardCommand($rep_search);
146  $ilTabs->setTabActive('maintenance');
147  } elseif ($this->edit_request->getRate360()) {
148  $ilTabs->clearTargets();
149  $ilTabs->setBackTarget(
150  $this->lng->txt("btn_back"),
151  $this->ctrl->getLinkTarget($this, "listAppraisees")
152  );
153 
154  $this->ctrl->setParameter($this, "rate360", 1);
155  $this->ctrl->saveParameter($this, "appr_id");
156 
157  $rep_search->setCallback(
158  $this,
159  'addRater',
160  array(
161  )
162  );
163 
164  // Set tabs
165  $this->ctrl->setReturn($this, 'editRaters');
166  $this->ctrl->forwardCommand($rep_search);
167  } else {
168  $ilTabs->activateTab("survey_360_appraisees");
169  $this->ctrl->setParameter($this, "appr360", 1);
170 
171  $rep_search->setCallback(
172  $this,
173  'addAppraisee',
174  array(
175  )
176  );
177 
178  // Set tabs
179  $this->ctrl->setReturn($this, 'listAppraisees');
180  $this->ctrl->forwardCommand($rep_search);
181  }
182  break;
183 
184  case 'ilsurveyratergui':
185  $ilTabs->activateTab("survey_360_edit_raters");
186  $rater_gui = new ilSurveyRaterGUI($this, $this->object);
187  $this->ctrl->forwardCommand($rater_gui);
188  break;
189 
190  default:
191  $cmd .= "Object";
192  $this->$cmd();
193  break;
194  }
195  }
196 
198  ?array $a_finished_ids = null
199  ): array {
200  $all_participants = $this->object->getSurveyParticipants($a_finished_ids, false, true);
201  $participant_ids = [];
202  foreach ($all_participants as $participant) {
203  if (isset($participant['usr_id'])) {
204  $participant_ids[] = $participant['usr_id'];
205  }
206  }
207 
208  $filtered_participant_ids = $this->access->filterUserIdsByRbacOrPositionOfCurrentUser(
209  'read_results',
210  'access_results',
211  $this->object->getRefId(),
212  $participant_ids
213  );
214 
215  $participants = [];
216  foreach ($all_participants as $username => $user_data) {
217  if (!($user_data['usr_id'] ?? false)) {
218  $participants[$username] = $user_data;
219  }
220  if (in_array(($user_data['usr_id'] ?? -1), $filtered_participant_ids)) {
221  $participants[$username] = $user_data;
222  }
223  }
224 
225  return $participants;
226  }
227 
228 
232  public function maintenanceObject(): void
233  {
234  $ilToolbar = $this->toolbar;
235 
236  if ($this->object->get360Mode()) {
237  $this->listAppraiseesObject();
238  return;
239  }
240 
241  //Btn Determine Competence Levels
242  if ($this->object->getMode() === ilObjSurvey::MODE_SELF_EVAL) {
243  $skmg_set = new ilSkillManagementSettings();
244  if ($this->object->getSkillService() && $skmg_set->isActivated()) {
245  $ilToolbar->addButton(
246  $this->lng->txt("survey_calc_skills"),
247  $this->ctrl->getLinkTargetByClass("ilsurveyskilldeterminationgui"),
248  ""
249  );
250  }
251  }
252 
253  $this->handleWriteAccess();
254  $this->setParticipantSubTabs("overview");
255 
256  $ilToolbar->addButton(
257  $this->lng->txt('svy_remove_all_participants'),
258  $this->ctrl->getLinkTarget($this, 'deleteAllUserData')
259  );
260 
261  $ilToolbar->addSeparator();
262 
263  if ($this->object->isAccessibleWithoutCode()) {
264  $ilToolbar->addButton(
265  $this->lng->txt("svy_invite_participants"),
266  $this->ctrl->getLinkTargetByClass('ilRepositorySearchGUI', '')
267  );
268  }
269 
270  $table_gui = new ilSurveyMaintenanceTableGUI($this, 'maintenance');
271 
272  $total = $this->filterSurveyParticipantsByAccess();
273  $data = array();
274  foreach ($total as $user_data) {
275  $finished = false;
276  if ($user_data["finished"]) {
277  $finished = $user_data["finished_tstamp"];
278  }
279  if (isset($user_data["active_id"])) {
280  $wt = $this->object->getWorkingtimeForParticipant($user_data["active_id"]);
281  $last_access = $this->object->getLastAccess($user_data["active_id"]);
282  $active_id = $user_data["active_id"];
283  } else {
284  $wt = 0;
285  $last_access = null;
286  $active_id = 0;
287  }
288  $data[] = array(
289  'id' => $active_id,
290  'name' => $user_data["sortname"],
291  'usr_id' => $user_data["usr_id"] ?? null,
292  'login' => $user_data["login"],
293  'last_access' => $last_access,
294  'workingtime' => $wt,
295  'finished' => $finished,
296  'invited' => $user_data["invited"] ?? false
297  );
298  }
299  $table_gui->setData($data);
300  $this->tpl->setVariable('ADM_CONTENT', $table_gui->getHTML());
301  }
302 
303  protected function isAnonymousListActive(): bool
304  {
305  $surveySetting = new ilSetting("survey");
306 
307  if ($surveySetting->get("anonymous_participants", false) && $this->object->hasAnonymizedResults() &&
308  $this->object->hasAnonymousUserList()) {
309  $end = $this->object->getEndDate();
310  if ($end && $end < date("YmdHis")) {
311  $min = (int) $surveySetting->get("anonymous_participants_min", '0');
312  $total = $this->object->getSurveyParticipants();
313  if (!$min || count($total) >= $min) {
314  return true;
315  }
316  }
317  }
318  return false;
319  }
320 
321  protected function setParticipantSubTabs(
322  string $active
323  ): void {
324  $ilTabs = $this->tabs;
325 
326  // not used in 360° mode
327 
328  // overview
329  $ilTabs->addSubTab(
330  "overview",
331  $this->lng->txt("svy_part_overview"),
332  $this->ctrl->getLinkTarget($this, 'maintenance')
333  );
334 
335  if ($this->isAnonymousListActive()) {
336  $ilTabs->addSubTab(
337  "anon_participants",
338  $this->lng->txt("svy_anonymous_participants_svy"),
339  $this->ctrl->getLinkTarget($this, 'listParticipants')
340  );
341  }
342 
343  if (!$this->object->isAccessibleWithoutCode()) {
344  $ilTabs->addSubTab(
345  "codes",
346  $this->lng->txt("svy_codes"),
347  $this->ctrl->getLinkTarget($this, 'codes')
348  );
349  }
350 
351 
352  $data = $this->object->getExternalCodeRecipients();
353  if (count($data)) {
354  $ilTabs->addSubTab(
355  "mail_survey_codes",
356  $this->lng->txt("mail_survey_codes"),
357  $this->ctrl->getLinkTarget($this, "mailCodes")
358  );
359  }
360 
361  $ilTabs->activateSubTab($active);
362  }
363 
364 
368  public function deleteAllUserDataObject(): void
369  {
370  $cgui = new ilConfirmationGUI();
371  $cgui->setHeaderText($this->lng->txt("confirm_delete_all_user_data"));
372  $cgui->setFormAction($this->ctrl->getFormAction($this, "deleteAllUserData"));
373  $cgui->setCancel($this->lng->txt("cancel"), "cancelDeleteAllUserData");
374  $cgui->setConfirm($this->lng->txt("confirm"), "confirmDeleteAllUserData");
375  $this->tpl->setContent($cgui->getHTML());
376  }
377 
381  public function confirmDeleteAllUserDataObject(): void
382  {
383  if ($this->access->checkAccess('write', '', $this->object->getRefId())) {
384  $this->object->deleteAllUserData();
385  } else {
386  $participants = $this->filterSurveyParticipantsByAccess();
387  foreach ($participants as $something => $participant_data) {
388  $this->object->removeSelectedSurveyResults([$participant_data['active_id']]);
389  }
390  }
391 
392  // #11558 - re-open closed appraisees
393  if ($this->object->get360Mode()) {
394  $this->object->openAllAppraisees();
395  }
396 
397  $this->tpl->setOnScreenMessage('success', $this->lng->txt("svy_all_user_data_deleted"), true);
398  $this->ctrl->redirect($this, "maintenance");
399  }
400 
404  public function cancelDeleteAllUserDataObject(): void
405  {
406  $this->ctrl->redirect($this, "maintenance");
407  }
408 
412  public function confirmDeleteSelectedUserDataObject(): void
413  {
414  $user_ids = $this->edit_request->getUserIds();
415  if (count($user_ids) > 0) {
416  $this->object->removeSelectedSurveyResults(array_filter($user_ids, static function ($i): bool {
417  return is_numeric($i);
418  }));
419 
420  $invitations = array_filter($user_ids, static function ($i): bool {
421  return strpos($i, "inv") === 0;
422  });
423  foreach ($invitations as $i) {
424  $this->invitation_manager->remove($this->object->getSurveyId(), (int) substr($i, 3));
425  }
426 
427  $this->tpl->setOnScreenMessage('success', $this->lng->txt("svy_selected_user_data_deleted"), true);
428  }
429  $this->ctrl->redirect($this, "maintenance");
430  }
431 
435  public function cancelDeleteSelectedUserDataObject(): void
436  {
437  $this->tpl->setOnScreenMessage('info', $this->lng->txt('msg_cancel'), true);
438  $this->ctrl->redirect($this, "maintenance");
439  }
440 
444  public function deleteSingleUserResultsObject(): void
445  {
446  $this->handleWriteAccess();
447 
448  $user_ids = $this->edit_request->getUserIds();
449  if (count($user_ids) === 0) {
450  $this->tpl->setOnScreenMessage('info', $this->lng->txt('no_checkbox'), true);
451  $this->ctrl->redirect($this, "maintenance");
452  }
453 
454  $this->tpl->setOnScreenMessage('question', $this->lng->txt("confirm_delete_single_user_data"));
455  $table_gui = new ilSurveyMaintenanceTableGUI($this, 'maintenance', true);
456  $total = $this->object->getSurveyParticipants(null, false, true);
457  $data = array();
458  foreach ($total as $user_data) {
459  if (in_array(($user_data['active_id'] ?? null), $user_ids)
460  || (($user_data['invited'] ?? false) && in_array("inv" . $user_data['usr_id'], $user_ids))) {
461  $last_access = $this->object->getLastAccess($user_data["active_id"] ?? 0);
462  $data[] = array(
463  'id' => $user_data["active_id"] ?? null,
464  'name' => $user_data["sortname"],
465  'login' => $user_data["login"] ?? null,
466  'last_access' => $last_access,
467  'finished' => $user_data["finished_tstamp"] ?? 0,
468  'usr_id' => $user_data["usr_id"] ?? null,
469  'invited' => $user_data["invited"] ?? null
470  );
471  }
472  }
473  $table_gui->setData($data);
474  $this->tpl->setVariable('ADM_CONTENT', $table_gui->getHTML());
475  }
476 
480  public function setCodeLanguageObject(): void
481  {
482  if (strcmp($this->edit_request->getLang(), "-1") !== 0) {
483  $ilUser = $this->user;
484  $ilUser->writePref("survey_code_language", $this->edit_request->getLang());
485  }
486  $this->tpl->setOnScreenMessage('success', $this->lng->txt('language_changed'), true);
487  $this->ctrl->redirect($this, 'codes');
488  }
489 
493  public function codesObject(): void
494  {
495  $ilUser = $this->user;
496  $ilToolbar = $this->toolbar;
497 
498  $this->handleWriteAccess();
499  $this->setParticipantSubTabs("codes");
500 
501  if ($this->object->isAccessibleWithoutCode()) {
502  $this->tpl->setOnScreenMessage('info', $this->lng->txt("survey_codes_no_anonymization"));
503  return;
504  }
505 
506  $default_lang = $ilUser->getPref("survey_code_language");
507 
508  // creation buttons
509  $ilToolbar->setFormAction($this->ctrl->getFormAction($this));
510 
511  $si = new ilTextInputGUI($this->lng->txt("new_survey_codes"), "nrOfCodes");
512  $si->setValue(1);
513  $si->setSize(3);
514  $ilToolbar->addInputItem($si, true);
515 
516  $this->gui->button(
517  $this->lng->txt("create"),
518  "createSurveyCodes"
519  )->submit()->toToolbar();
520 
521  $ilToolbar->addSeparator();
522 
523  $this->gui->button(
524  $this->lng->txt("import_from_file"),
525  "importExternalMailRecipientsFromFileForm"
526  )->submit()->toToolbar();
527 
528  $this->gui->button(
529  $this->lng->txt("import_from_text"),
530  "importExternalMailRecipientsFromTextForm"
531  )->submit()->toToolbar();
532 
533  $ilToolbar->addSeparator();
534 
535  $this->gui->button(
536  $this->lng->txt("svy_import_codes"),
537  "importAccessCodes"
538  )->submit()->toToolbar();
539 
540  $ilToolbar->addSeparator();
541 
542  $languages = $this->lng->getInstalledLanguages();
543  $options = array();
544  $this->lng->loadLanguageModule("meta");
545  foreach ($languages as $lang) {
546  $options[$lang] = $this->lng->txt("meta_l_" . $lang);
547  }
548  $si = new ilSelectInputGUI($this->lng->txt("survey_codes_lang"), "lang");
549  $si->setOptions($options);
550  $si->setValue($default_lang);
551  $ilToolbar->addInputItem($si, true);
552 
553  $this->gui->button(
554  $this->lng->txt("set"),
555  "setCodeLanguage"
556  )->submit()->toToolbar();
557 
558 
559  $table_gui = new ilSurveyCodesTableGUI($this, 'codes');
560  $survey_codes = $this->object->getSurveyCodesTableData(null, $default_lang);
561  $table_gui->setData($survey_codes);
562  $this->tpl->setContent($table_gui->getHTML());
563  }
564 
565  public function editCodesObject(): void
566  {
567  $ids = $this->edit_request->getCodeIds();
568  if (count($ids) === 0) {
569  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('no_checkbox'), true);
570  $this->ctrl->redirect($this, 'codes');
571  }
572 
573  $this->handleWriteAccess();
574  $this->setParticipantSubTabs("codes");
575 
576  $table_gui = new ilSurveyCodesEditTableGUI($this, 'editCodes');
577  $table_gui->setData($this->object->getSurveyCodesTableData($ids));
578  $this->tpl->setContent($table_gui->getHTML());
579  }
580 
581  public function updateCodesObject(): void
582  {
583  $codes = $this->edit_request->getCodes();
584  $mails = $this->edit_request->getCodesPar("mail");
585  $lnames = $this->edit_request->getCodesPar("lname");
586  $fnames = $this->edit_request->getCodesPar("fname");
587  $sents = $this->edit_request->getCodesPar("sent");
588  if (count($codes) === 0) {
589  $this->ctrl->redirect($this, 'codes');
590  }
591 
592  $errors = array();
593  $error_message = "";
594  foreach ($codes as $id) {
595  if (!$this->object->updateCode(
596  $id,
597  $mails[$id] ?? "",
598  $lnames[$id] ?? "",
599  $fnames[$id] ?? "",
600  $sents[$id] ?? 0
601  )) {
602  $errors[] = array($mails[$id], $lnames[$id], $fnames[$id]);
603  }
604  }
605  if (empty($errors)) {
606  $this->tpl->setOnScreenMessage('success', $this->lng->txt('settings_saved'), true);
607  } else {
608  foreach ($errors as $error) {
609  $error_message .= sprintf($this->lng->txt("error_save_code"), $error[0], $error[1], $error[2]);
610  }
611  $this->tpl->setOnScreenMessage('failure', $error_message, true);
612  }
613 
614  $this->ctrl->redirect($this, 'codes');
615  }
616 
617  public function deleteCodesConfirmObject(): void
618  {
619  $codes = $this->edit_request->getCodes();
620 
621  $data = $this->object->getSurveyCodesTableData($codes);
622  $data = array_filter($data, static function ($item): bool {
623  return !$item["used"];
624  });
625  if (count($data) > 0) {
626  $cgui = new ilConfirmationGUI();
627  $cgui->setHeaderText($this->lng->txt("survey_code_delete_sure"));
628 
629  $cgui->setFormAction($this->ctrl->getFormAction($this));
630  $cgui->setCancel($this->lng->txt("cancel"), "codes");
631  $cgui->setConfirm($this->lng->txt("confirm"), "deleteCodes");
632 
633  foreach ($data as $item) {
634  $title = array($item["code"]);
635  $title[] = $item["email"] ?? "";
636  $title[] = $item["last_name"] ?? "";
637  $title[] = $item["first_name"] ?? "";
638  $title = implode(", ", $title);
639 
640  $cgui->addItem("chb_code[]", $item["code"], $title);
641  }
642 
643  $this->tpl->setContent($cgui->getHTML());
644  } else {
645  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('svy_please_select_unused_codes'), true);
646  $this->ctrl->redirect($this, 'codes');
647  }
648  }
649 
653  public function deleteCodesObject(): void
654  {
655  $codes = $this->edit_request->getCodes();
656  if (count($codes) > 0) {
657  foreach ($codes as $survey_code) {
658  $this->object->deleteSurveyCode($survey_code);
659  }
660  $this->tpl->setOnScreenMessage('success', $this->lng->txt('codes_deleted'), true);
661  } else {
662  $this->tpl->setOnScreenMessage('info', $this->lng->txt('no_checkbox'), true);
663  }
664  $this->ctrl->redirect($this, 'codes');
665  }
666 
670  public function exportCodesObject(): void
671  {
672  $codes = $this->edit_request->getCodes();
673  if (count($codes) > 0) {
674  $export = $this->object->getSurveyCodesForExport(null, $codes);
675  ilUtil::deliverData($export, ilFileUtils::getASCIIFilename($this->object->getTitle() . ".csv"));
676  } else {
677  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("no_checkbox"), true);
678  $this->ctrl->redirect($this, 'codes');
679  }
680  }
681 
685  public function exportAllCodesObject(): void
686  {
687  $export = $this->object->getSurveyCodesForExport();
688  ilUtil::deliverData($export, ilFileUtils::getASCIIFilename($this->object->getTitle() . ".csv"));
689  }
690 
694  protected function importAccessCodesObject(): void
695  {
696  $this->handleWriteAccess();
697  $this->setParticipantSubTabs("codes");
698  $form_import_file = $this->getAccessCodeImportForm();
699  $this->tpl->setContent($form_import_file->getHTML());
700  }
701 
703  {
704  $form_import_file = new ilPropertyFormGUI();
705  $form_import_file->setFormAction($this->ctrl->getFormAction($this));
706  $form_import_file->setTableWidth("100%");
707  $form_import_file->setId("codes_import_file");
708 
709  $headerfile = new ilFormSectionHeaderGUI();
710  $headerfile->setTitle($this->lng->txt("svy_import_codes"));
711  $form_import_file->addItem($headerfile);
712 
713  $export_file = new ilFileInputGUI($this->lng->txt("codes"), "codes");
714  $export_file->setInfo(sprintf(
715  $this->lng->txt('svy_import_codes_info'),
716  $this->lng->txt("export_all_survey_codes")
717  ));
718  $export_file->setSuffixes(array("csv"));
719  $export_file->setRequired(true);
720  $form_import_file->addItem($export_file);
721 
722  $form_import_file->addCommandButton("importAccessCodesAction", $this->lng->txt("import"));
723  $form_import_file->addCommandButton("codes", $this->lng->txt("cancel"));
724 
725  return $form_import_file;
726  }
727 
731  protected function importAccessCodesActionObject(): void
732  {
733  $form = $this->getAccessCodeImportForm();
734 
735  if ($form->checkInput()) {
736  $existing = array();
737  foreach ($this->object->getSurveyCodesTableData() as $item) {
738  $existing[$item["code"]] = $item["id"];
739  }
740 
741  $reader = new CSVReader();
742  $reader->open($_FILES['codes']['tmp_name']);
743  foreach ($reader->getCsvAsArray() as $row) {
744  // numeric check of used column due to #26176
745  $code = $row[0] ?? "";
746  if ($code === "") {
747  continue;
748  }
749  $email = $row[1] ?? "";
750  if (!is_int(strpos($email, "@")) && $email !== "") {
751  continue;
752  }
753  $last_name = $row[2] ?? "";
754  $first_name = $row[3] ?? "";
755  $created = time();
756 
757  // unique code?
758  if (!array_key_exists($code, $existing)) {
759  // could be date or datetime
760  /*try {
761  if (strlen($created) === 10) {
762  $created = new ilDate($created, IL_CAL_DATE);
763  } else {
764  $created = new ilDateTime($created, IL_CAL_DATETIME);
765  }
766  $created = $created->get(IL_CAL_UNIX);
767  } catch (Exception $e) {
768  $this->tpl->setOnScreenMessage('failure', $e->getMessage(), true);
769  $this->ctrl->redirect($this, 'codes');
770  }*/
771 
772  $user_data = array(
773  "email" => $email
774  ,"lastname" => $last_name
775  ,"firstname" => $first_name
776  );
777  $this->object->importSurveyCode($code, $created, $user_data);
778  }
779  }
780 
781  $this->tpl->setOnScreenMessage('success', $this->lng->txt('codes_created'), true);
782  $this->ctrl->redirect($this, 'codes');
783  } else {
784  $form->setValuesByPost();
785  $this->handleWriteAccess();
786  $this->setParticipantSubTabs("codes");
787  $this->tpl->setContent($form->getHTML());
788  }
789  }
790 
794  public function createSurveyCodesObject(): void
795  {
796  if ($this->edit_request->getNrOfCodes() > 0) {
797  $ids = $this->code_manager->addCodes($this->edit_request->getNrOfCodes());
798  $this->tpl->setOnScreenMessage('success', $this->lng->txt('codes_created'), true);
799  $this->ctrl->setParameter($this, "new_ids", implode(";", $ids));
800  $this->ctrl->redirect($this, 'editCodes');
801  } else {
802  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("enter_valid_number_of_codes"), true);
803  $this->ctrl->redirect($this, 'codes');
804  }
805  }
806 
807  public function insertSavedMessageObject(): void
808  {
809  $this->handleWriteAccess();
810  $this->setParticipantSubTabs("codes");
811 
812  $form_gui = new FormMailCodesGUI($this);
813  $form_gui->setValuesByPost();
814  try {
815  if ($form_gui->getSavedMessages()->getValue() > 0) {
816  $ilUser = $this->user;
817  $settings = $this->object->getUserSettings($ilUser->getId(), 'savemessage');
818  $form_gui->getMailMessage()->setValue($settings[$form_gui->getSavedMessages()->getValue()]['value']);
819  $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_message_inserted'));
820  } else {
821  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('msg_no_message_inserted'));
822  }
823  } catch (Exception $e) {
824  $ilLog = $this->log;
825  $ilLog->write('Error: ' . $e->getMessage());
826  }
827  $this->tpl->setVariable("ADM_CONTENT", $form_gui->getHTML());
828  }
829 
830  public function deleteSavedMessageObject(): void
831  {
832  $this->handleWriteAccess();
833  $this->setParticipantSubTabs("codes");
834 
835  $form_gui = new FormMailCodesGUI($this);
836  $form_gui->setValuesByPost();
837  try {
838  if ($form_gui->getSavedMessages()->getValue() > 0) {
839  $this->object->deleteUserSettings($form_gui->getSavedMessages()->getValue());
840  $form_gui = new FormMailCodesGUI($this);
841  $form_gui->setValuesByPost();
842  $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_message_deleted'));
843  } else {
844  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('msg_no_message_deleted'));
845  }
846  } catch (Exception $e) {
847  $ilLog = $this->log;
848  $ilLog->write('Error: ' . $e->getMessage());
849  }
850  $this->tpl->setVariable("ADM_CONTENT", $form_gui->getHTML());
851  }
852 
853  public function mailCodesObject(): void
854  {
855  $this->handleWriteAccess();
856  $this->setParticipantSubTabs("mail_survey_codes");
857 
858  $mailData['m_subject'] =
859  $this->edit_request->getCodeMailPart("subject")
860  ?: sprintf($this->lng->txt('default_codes_mail_subject'), $this->object->getTitle());
861  $mailData['m_message'] =
862  $this->edit_request->getCodeMailPart("message")
863  ?: $this->lng->txt('default_codes_mail_message');
864  $mailData['m_notsent'] =
865  $this->edit_request->getCodeMailPart("notsent")
866  ?: '1';
867 
868  $form_gui = new FormMailCodesGUI($this);
869  $form_gui->setValuesByArray($mailData);
870  $this->tpl->setVariable("ADM_CONTENT", $form_gui->getHTML());
871  }
872 
873  public function sendCodesMailObject(): void
874  {
875  $ilUser = $this->user;
876 
877  $this->handleWriteAccess();
878  $this->setParticipantSubTabs("mail_survey_codes");
879 
880  $form_gui = new FormMailCodesGUI($this);
881  if ($form_gui->checkInput()) {
882  $url_exists = strpos($this->edit_request->getCodeMailPart("message"), '[url]') !== false;
883  if (!$url_exists) {
884  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('please_enter_mail_url'));
885  $form_gui->setValuesByPost();
886  } else {
887  if ($this->edit_request->getSaveMessage() === 1) {
888  $ilUser = $this->user;
889  $title = ($this->edit_request->getSaveMessageTitle())
890  ?: ilStr::subStr($this->edit_request->getCodeMailPart("message"), 0, 40) . '...';
891  $this->object->saveUserSettings($ilUser->getId(), 'savemessage', $title, $this->edit_request->getCodeMailPart("message"));
892  }
893 
894  $lang = $ilUser->getPref("survey_code_language");
895  if (!$lang) {
896  $lang = $this->lng->getDefaultLanguage();
897  }
898  $this->object->sendCodes(
899  $this->edit_request->getCodeMailPart("notsent"),
900  $this->edit_request->getCodeMailPart("subject"),
901  nl2br($this->edit_request->getCodeMailPart("message")),
902  $lang
903  );
904  $this->tpl->setOnScreenMessage('success', $this->lng->txt('mail_sent'), true);
905  $this->ctrl->redirect($this, 'mailCodes');
906  }
907  } else {
908  $form_gui->setValuesByPost();
909  }
910  $this->tpl->setVariable("ADM_CONTENT", $form_gui->getHTML());
911  }
912 
914  {
915  if (trim($this->edit_request->getExternalText())) {
916  $data = preg_split("/[\n\r]/", $this->edit_request->getExternalText());
917  $fields = explode(";", array_shift($data));
918  if (!in_array('email', $fields, true)) {
919  $this->edit_manager->setExternalText($this->edit_request->getExternalText());
920  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('err_external_rcp_no_email_column'), true);
921  $this->ctrl->redirect($this, 'importExternalMailRecipientsFromTextForm');
922  }
923  $existingdata = $this->object->getExternalCodeRecipients();
924  $existingcolumns = array();
925  if (count($existingdata)) {
926  $first = array_shift($existingdata);
927  foreach ($first as $key => $value) {
928  $existingcolumns[] = $key;
929  }
930  }
931  $founddata = array();
932  foreach ($data as $datarow) {
933  $row = explode(";", $datarow);
934  if (count($row) === count($fields)) {
935  $dataset = array();
936  foreach ($fields as $idx => $fieldname) {
937  if (count($existingcolumns)) {
938  if (array_key_exists($idx, $existingcolumns)) {
939  $dataset[$fieldname] = $row[$idx];
940  }
941  } else {
942  $dataset[$fieldname] = $row[$idx];
943  }
944  }
945  if ($dataset['email'] !== '') {
946  $this->addCodeForExternal(
947  $dataset['email'],
948  $dataset['lastname'] ?? "",
949  $dataset['firstname'] ?? ""
950  );
951  }
952  }
953  }
954  $this->tpl->setOnScreenMessage('success', $this->lng->txt('external_recipients_imported'), true);
955  $this->ctrl->redirect($this, 'codes');
956  }
957 
958  $this->ctrl->redirect($this, 'importExternalMailRecipientsFromTextForm');
959  }
960 
964  public function addCodeForExternal(
965  string $email,
966  string $lastname,
967  string $firstname
968  ): int {
969  $code = $this->data_manager->code("")
970  ->withEmail($email)
971  ->withLastName($lastname)
972  ->withFirstName($firstname);
973  $code_id = $this->code_manager->add($code);
974  return $code_id;
975  }
976 
977  // used for importing external participants
978  // @todo move to manager/transformation class
979  protected function _convertCharset(
980  string $a_string,
981  string $a_from_charset = "",
982  string $a_to_charset = "UTF-8"
983  ): string {
984  if (extension_loaded("mbstring")) {
985  if (!$a_from_charset) {
986  mb_detect_order("UTF-8, ISO-8859-1, Windows-1252, ASCII");
987  $a_from_charset = mb_detect_encoding($a_string);
988  }
989  if (strtoupper($a_from_charset) !== $a_to_charset) {
990  return mb_convert_encoding($a_string, $a_to_charset, $a_from_charset);
991  }
992  }
993  return $a_string;
994  }
995 
996  // @todo move to manager/transformation class
997  protected function removeUTF8Bom(string $a_text): string
998  {
999  $bom = pack('H*', 'EFBBBF');
1000  return preg_replace('/^' . $bom . '/', '', $a_text);
1001  }
1002 
1004  {
1005  $this->handleWriteAccess();
1007 
1008  if (!$form->checkInput()) {
1009  $this->setParticipantSubTabs("codes");
1010  $this->tpl->setContent($form->getHTML());
1011  return;
1012  }
1013 
1014  if (trim($_FILES['externalmails']['tmp_name'])) {
1015  $reader = new CSVReader();
1016  $reader->open($_FILES['externalmails']['tmp_name']);
1017  $data = $reader->getCsvAsArray();
1018  $fields = array_shift($data);
1019  foreach ($fields as $idx => $field) {
1020  $fields[$idx] = $this->removeUTF8Bom($field);
1021  }
1022  if (!in_array('email', $fields, true)) {
1023  $reader->close();
1024  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('err_external_rcp_no_email'), true);
1025  $this->ctrl->redirect($this, 'codes');
1026  }
1027  $existingdata = $this->object->getExternalCodeRecipients();
1028  $existingcolumns = array();
1029  if (count($existingdata)) {
1030  $first = array_shift($existingdata);
1031  foreach ($first as $key => $value) {
1032  $existingcolumns[] = $key;
1033  }
1034  }
1035 
1036  $founddata = array();
1037  foreach ($data as $row) {
1038  if (count($row) === count($fields)) {
1039  $dataset = array();
1040  foreach ($fields as $idx => $fieldname) {
1041  // #14811
1042  $row[$idx] = $this->_convertCharset($row[$idx]);
1043 
1044  if (count($existingcolumns)) {
1045  if (array_key_exists($idx, $existingcolumns)) {
1046  $dataset[$fieldname] = $row[$idx];
1047  }
1048  } else {
1049  $dataset[$fieldname] = $row[$idx];
1050  }
1051  }
1052  if ($dataset['email'] !== '') {
1053  $founddata[] = $dataset;
1054  $this->addCodeForExternal(
1055  $dataset['email'],
1056  $dataset['lastname'] ?? "",
1057  $dataset['firstname'] ?? ""
1058  );
1059  }
1060  }
1061  }
1062  $reader->close();
1063 
1064  if (count($founddata)) {
1065  $this->tpl->setOnScreenMessage('success', $this->lng->txt('external_recipients_imported'), true);
1066  }
1067  }
1068 
1069  $this->ctrl->redirect($this, 'codes');
1070  }
1071 
1073  {
1074  $this->handleWriteAccess();
1075  $this->setParticipantSubTabs("codes");
1077  $this->tpl->setContent($form->getHTML());
1078  }
1079 
1081  {
1082  $ilAccess = $this->access;
1083 
1084  $form_import_file = new ilPropertyFormGUI();
1085  $form_import_file->setFormAction($this->ctrl->getFormAction($this));
1086  $form_import_file->setTableWidth("100%");
1087  $form_import_file->setId("codes_import_file");
1088 
1089  $headerfile = new ilFormSectionHeaderGUI();
1090  $headerfile->setTitle($this->lng->txt("import_from_file"));
1091  $form_import_file->addItem($headerfile);
1092 
1093  $externalmails = new ilFileInputGUI($this->lng->txt("externalmails"), "externalmails");
1094  $externalmails->setInfo($this->lng->txt('externalmails_info'));
1095  $externalmails->setRequired(true);
1096  $form_import_file->addItem($externalmails);
1097  if ($ilAccess->checkAccess("write", "", $this->edit_request->getRefId())) {
1098  $form_import_file->addCommandButton("importExternalRecipientsFromFile", $this->lng->txt("import"));
1099  }
1100  if ($ilAccess->checkAccess("write", "", $this->edit_request->getRefId())) {
1101  $form_import_file->addCommandButton("codes", $this->lng->txt("cancel"));
1102  }
1103  return $form_import_file;
1104  }
1105 
1107  {
1108  $ilAccess = $this->access;
1109 
1110  $this->handleWriteAccess();
1111  $this->setParticipantSubTabs("mail_survey_codes");
1112 
1113  $form_import_text = new ilPropertyFormGUI();
1114  $form_import_text->setFormAction($this->ctrl->getFormAction($this));
1115  $form_import_text->setTableWidth("100%");
1116  $form_import_text->setId("codes_import_text");
1117 
1118  $headertext = new ilFormSectionHeaderGUI();
1119  $headertext->setTitle($this->lng->txt("import_from_text"));
1120  $form_import_text->addItem($headertext);
1121 
1122  $inp = new ilTextAreaInputGUI($this->lng->txt('externaltext'), 'externaltext');
1123  $external_text = $this->edit_manager->getExternalText();
1124  if ($external_text !== "") {
1125  $inp->setValue($external_text);
1126  } else {
1127  // $this->lng->txt('mail_import_example1') #14897
1128  $inp->setValue("email;firstname;lastname\n" . $this->lng->txt('mail_import_example2') . "\n" . $this->lng->txt('mail_import_example3') . "\n");
1129  }
1130  $inp->setRequired(true);
1131  $inp->setCols(80);
1132  $inp->setRows(10);
1133  $inp->setInfo($this->lng->txt('externaltext_info'));
1134  $form_import_text->addItem($inp);
1135  $this->edit_manager->setExternalText("");
1136 
1137  if ($ilAccess->checkAccess("write", "", $this->edit_request->getRefId())) {
1138  $form_import_text->addCommandButton("importExternalRecipientsFromText", $this->lng->txt("import"));
1139  }
1140  if ($ilAccess->checkAccess("write", "", $this->edit_request->getRefId())) {
1141  $form_import_text->addCommandButton("codes", $this->lng->txt("cancel"));
1142  }
1143 
1144  $this->tpl->setContent($form_import_text->getHTML());
1145  }
1146 
1147  //
1148  // 360°
1149  //
1150 
1151  public function listAppraiseesObject(): void
1152  {
1153  $ilToolbar = $this->toolbar;
1154  $lng = $this->lng;
1155  $ilCtrl = $this->ctrl;
1156 
1157  $this->handleWriteAccess();
1158 
1159  $this->ctrl->setParameter($this, "appr360", 1);
1160 
1162  $this,
1163  $ilToolbar,
1164  array(
1165  'auto_complete_name' => $this->lng->txt('user'),
1166  'submit_name' => $this->lng->txt('add'),
1167  'add_search' => true,
1168  'add_from_container' => $this->ref_id
1169  )
1170  );
1171 
1172  // competence calculations
1173  $skmg_set = new ilSkillManagementSettings();
1174  if ($this->object->getSkillService() && $skmg_set->isActivated()) {
1175  $ilToolbar->addSeparator();
1176  $ilToolbar->addButton(
1177  $lng->txt("survey_calc_skills"),
1178  $ilCtrl->getLinkTargetByClass("ilsurveyskilldeterminationgui"),
1179  ""
1180  );
1181  }
1182 
1183  $ilToolbar->addSeparator();
1184  $ilToolbar->addButton(
1185  $this->lng->txt('svy_delete_all_user_data'),
1186  $this->ctrl->getLinkTarget($this, 'deleteAllUserData')
1187  );
1188 
1189  $this->ctrl->setParameter($this, "appr360", "");
1190 
1191  $tbl = new ilSurveyAppraiseesTableGUI($this, "listAppraisees");
1192  $tbl->setData($this->object->getAppraiseesData());
1193  $this->tpl->setContent($tbl->getHTML());
1194  }
1195 
1196  public function addAppraisee(
1197  array $a_user_ids
1198  ): void {
1199  if (count($a_user_ids)) {
1200  // #13319
1201  foreach (array_unique($a_user_ids) as $user_id) {
1202  $this->object->addAppraisee($user_id);
1203  }
1204 
1205  $this->tpl->setOnScreenMessage('success', $this->lng->txt("settings_saved"), true);
1206  }
1207  $this->ctrl->redirect($this, "listAppraisees");
1208  }
1209 
1210  public function confirmDeleteAppraiseesObject(): void
1211  {
1212  $ilTabs = $this->tabs;
1213 
1214  $appr_ids = $this->edit_request->getAppraiseeIds();
1215  if (count($appr_ids) === 0) {
1216  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("select_one"), true);
1217  $this->ctrl->redirect($this, "listAppraisees");
1218  }
1219 
1220  $ilTabs->clearTargets();
1221  $ilTabs->setBackTarget(
1222  $this->lng->txt("btn_back"),
1223  $this->ctrl->getLinkTarget($this, "listAppraisees")
1224  );
1225 
1226  $cgui = new ilConfirmationGUI();
1227  $cgui->setHeaderText($this->lng->txt("survey_360_sure_delete_appraises"));
1228 
1229  $cgui->setFormAction($this->ctrl->getFormAction($this, "deleteAppraisees"));
1230  $cgui->setCancel($this->lng->txt("cancel"), "listAppraisees");
1231  $cgui->setConfirm($this->lng->txt("confirm"), "deleteAppraisees");
1232 
1233  $data = $this->object->getAppraiseesData();
1234 
1235  $count = 0;
1236  foreach ($appr_ids as $id) {
1237  if (isset($data[$id]) && !$data[$id]["closed"]) {
1238  $cgui->addItem("appr_id[]", $id, ilUserUtil::getNamePresentation($id));
1239  $count++;
1240  }
1241  }
1242 
1243  if (!$count) {
1244  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("select_one"), true);
1245  $this->ctrl->redirect($this, "listAppraisees");
1246  }
1247 
1248  $this->tpl->setContent($cgui->getHTML());
1249  }
1250 
1251  public function deleteAppraiseesObject(): void
1252  {
1253  $appr_ids = $this->edit_request->getAppraiseeIds();
1254  if (count($appr_ids) > 0) {
1255  $data = $this->object->getAppraiseesData();
1256 
1257  foreach ($appr_ids as $id) {
1258  // #11285
1259  if (isset($data[$id]) && !$data[$id]["closed"]) {
1260  $this->object->deleteAppraisee($id);
1261  }
1262  }
1263 
1264  $this->tpl->setOnScreenMessage('success', $this->lng->txt("settings_saved"), true);
1265  }
1266 
1267  $this->ctrl->redirect($this, "listAppraisees");
1268  }
1269 
1270  public function handleRatersAccess(): ?int
1271  {
1272  $ilAccess = $this->access;
1273  $ilUser = $this->user;
1274 
1275  if ($ilAccess->checkAccess("write", "", $this->ref_id)) {
1276  $appr_id = $this->edit_request->getAppraiseeId();
1277  if (!$appr_id) {
1278  $this->ctrl->redirect($this, "listAppraisees");
1279  }
1280  return $appr_id;
1281  } elseif ($this->feature_config->usesAppraisees() &&
1282  $this->object->get360SelfRaters() &&
1283  $this->object->isAppraisee($ilUser->getId()) &&
1284  !$this->object->isAppraiseeClosed($ilUser->getId())) {
1285  return $ilUser->getId();
1286  }
1287  $this->ctrl->redirect($this->parent_gui, "infoScreen");
1288  return null;
1289  }
1290 
1291  protected function storeMailSent(): void
1292  {
1293  $appr_id = $this->handleRatersAccess();
1294  $all_data = $this->object->getRatersData($appr_id);
1295 
1296  $recs = json_decode(base64_decode($this->edit_request->getRecipients()));
1297  foreach ($all_data as $rec_id => $rater) {
1298  $sent = false;
1299  if (($rater["login"] != "" && in_array($rater["login"], $recs, true)) ||
1300  ($rater["email"] != "" && in_array($rater["email"], $recs, true))) {
1301  $sent = true;
1302  }
1303  if ($sent) {
1304  $this->object->set360RaterSent(
1305  $appr_id,
1306  strpos($rec_id, "a") === 0 ? 0 : (int) substr($rec_id, 1),
1307  strpos($rec_id, "u") === 0 ? 0 : (int) substr($rec_id, 1)
1308  );
1309  }
1310  }
1311  $this->ctrl->setParameter($this, "appr_id", $appr_id);
1312  $this->ctrl->redirect($this, "editRaters");
1313  }
1314 
1315  public function editRatersObject(): void
1316  {
1317  if ($this->edit_request->getReturnedFromMail() === 1) {
1318  $this->storeMailSent();
1319  }
1320 
1321  $ilTabs = $this->tabs;
1322  $ilToolbar = $this->toolbar;
1323  $ilAccess = $this->access;
1324  $ilTabs->activateTab("survey_360_edit_raters");
1325  $appr_id = $this->handleRatersAccess();
1326 
1327  $has_write = $ilAccess->checkAccess("write", "", $this->ref_id);
1328  if ($has_write) {
1329  $ilTabs->clearTargets();
1330  $ilTabs->setBackTarget(
1331  $this->lng->txt("btn_back"),
1332  $this->ctrl->getLinkTarget($this, "listAppraisees")
1333  );
1334  }
1335 
1336  $this->ctrl->setParameter($this, "appr_id", $appr_id);
1337  $this->ctrl->setParameter($this, "rate360", 1);
1338 
1339  $ilToolbar->addButton(
1340  $this->lng->txt("svy_add_rater"),
1341  $this->ctrl->getLinkTargetByClass("ilSurveyRaterGUI", "add")
1342  );
1343 
1344  // #13320
1345  $url = ilLink::_getStaticLink($this->object->getRefId());
1346 
1347  $tbl = new ilSurveyAppraiseesTableGUI($this, "editRaters", true, !$this->object->isAppraiseeClosed($appr_id), $url); // #11285
1348  $tbl->setData($this->object->getRatersData($appr_id));
1349  $this->tpl->setContent($tbl->getHTML());
1350  }
1351 
1353  ?ilPropertyFormGUI $a_form = null
1354  ): void {
1355  $ilTabs = $this->tabs;
1356  $ilAccess = $this->access;
1357 
1358  $appr_id = $this->handleRatersAccess();
1359  $this->ctrl->setParameter($this, "appr_id", $appr_id);
1360 
1361  $has_write = $ilAccess->checkAccess("write", "", $this->ref_id);
1362  if ($has_write) {
1363  $ilTabs->clearTargets();
1364  $ilTabs->setBackTarget(
1365  $this->lng->txt("btn_back"),
1366  $this->ctrl->getLinkTarget($this, "editRaters")
1367  );
1368  }
1369 
1370  if (!$a_form) {
1371  $a_form = $this->initExternalRaterForm($appr_id);
1372  }
1373 
1374  $this->tpl->setContent($a_form->getHTML());
1375  }
1376 
1377  protected function initExternalRaterForm(
1378  int $appr_id
1379  ): ilPropertyFormGUI {
1380  $form = new ilPropertyFormGUI();
1381  $form->setFormAction($this->ctrl->getFormAction($this, "addExternalRater"));
1382  $form->setTitle($this->lng->txt("survey_360_add_external_rater") .
1383  ": " . ilUserUtil::getNamePresentation($appr_id));
1384 
1385  $email = new ilEMailInputGUI($this->lng->txt("email"), "email");
1386  $email->setRequired(true);
1387  $form->addItem($email);
1388 
1389  $lname = new ilTextInputGUI($this->lng->txt("lastname"), "lname");
1390  $lname->setSize(30);
1391  $form->addItem($lname);
1392 
1393  $fname = new ilTextInputGUI($this->lng->txt("firstname"), "fname");
1394  $fname->setSize(30);
1395  $form->addItem($fname);
1396 
1397  $form->addCommandButton("addExternalRater", $this->lng->txt("save"));
1398  $form->addCommandButton("editRaters", $this->lng->txt("cancel"));
1399 
1400  return $form;
1401  }
1402 
1403  public function addExternalRaterObject(): void
1404  {
1405  $appr_id = $this->edit_request->getAppraiseeId();
1406  if (!$appr_id) {
1407  $this->ctrl->redirect($this, "listAppraisees");
1408  }
1409 
1410  $this->ctrl->setParameter($this, "appr_id", $appr_id);
1411 
1412  $form = $this->initExternalRaterForm($appr_id);
1413  if ($form->checkInput()) {
1414  $code_id = $this->addCodeForExternal(
1415  $form->getInput("email"),
1416  $form->getInput("lname"),
1417  $form->getInput("fname")
1418  );
1419 
1420  $this->object->addRater($appr_id, 0, $code_id);
1421 
1422  $this->tpl->setOnScreenMessage('success', $this->lng->txt("settings_saved"), true);
1423  $this->ctrl->setParameter($this, "appr_id", $appr_id);
1424  $this->ctrl->redirect($this, "editRaters");
1425  }
1426 
1427  $form->setValuesByPost();
1428  $this->addExternalRaterFormObject($form);
1429  }
1430 
1431  public function addRater(
1432  array $a_user_ids
1433  ): void {
1434  $ilAccess = $this->access;
1435  $ilUser = $this->user;
1436 
1437  $appr_id = $this->handleRatersAccess();
1438 
1439  if (count($a_user_ids)) {
1440  // #13319
1441  foreach (array_unique($a_user_ids) as $user_id) {
1442  if ($ilAccess->checkAccess("write", "", $this->ref_id) ||
1443  $this->object->get360SelfEvaluation() ||
1444  $user_id != $ilUser->getId()) {
1445  if ($appr_id != $user_id) {
1446  $this->object->addRater($appr_id, $user_id);
1447  $this->tpl->setOnScreenMessage('success', $this->lng->txt("settings_saved"), true);
1448  } else {
1449  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("svy_appraisses_cannot_be_raters"), true);
1450  }
1451  }
1452  }
1453  }
1454 
1455  $this->ctrl->setParameter($this, "appr_id", $appr_id);
1456  $this->ctrl->redirect($this, "editRaters");
1457  }
1458 
1459  public function confirmDeleteRatersObject(): void
1460  {
1461  $ilTabs = $this->tabs;
1462 
1463  $rater_ids = $this->edit_request->getRaterIds();
1464  $appr_id = $this->handleRatersAccess();
1465  $this->ctrl->setParameter($this, "appr_id", $appr_id);
1466  if (count($rater_ids) === 0) {
1467  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("select_one"), true);
1468  $this->ctrl->redirect($this, "editRaters");
1469  }
1470 
1471  $ilTabs->clearTargets();
1472  $ilTabs->setBackTarget(
1473  $this->lng->txt("btn_back"),
1474  $this->ctrl->getLinkTarget($this, "editRaters")
1475  );
1476 
1477  $cgui = new ilConfirmationGUI();
1478  $cgui->setHeaderText(sprintf(
1479  $this->lng->txt("survey_360_sure_delete_raters"),
1481  ));
1482 
1483  $cgui->setFormAction($this->ctrl->getFormAction($this, "deleteRaters"));
1484  $cgui->setCancel($this->lng->txt("cancel"), "editRaters");
1485  $cgui->setConfirm($this->lng->txt("confirm"), "deleteRaters");
1486 
1487  $data = $this->object->getRatersData($appr_id);
1488 
1489  foreach ($rater_ids as $id) {
1490  if (isset($data[$id])) {
1491  $cgui->addItem("rtr_id[]", $id, $data[$id]["lastname"] . ", " .
1492  $data[$id]["firstname"] . " (" . $data[$id]["email"] . ")");
1493  }
1494  }
1495 
1496  $this->tpl->setContent($cgui->getHTML());
1497  }
1498 
1499  public function deleteRatersObject(): void
1500  {
1501  $appr_id = $this->handleRatersAccess();
1502  $this->ctrl->setParameter($this, "appr_id", $appr_id);
1503 
1504  $rater_ids = $this->edit_request->getRaterIds();
1505  if (count($rater_ids) > 0) {
1506  $data = $this->object->getRatersData($appr_id);
1507 
1508  foreach ($rater_ids as $id) {
1509  if (isset($data[$id])) {
1510  if (strpos($id, "u") === 0) {
1511  $this->object->deleteRater($appr_id, substr($id, 1));
1512  } else {
1513  $this->object->deleteRater($appr_id, 0, substr($id, 1));
1514  }
1515  }
1516  }
1517 
1518  $this->tpl->setOnScreenMessage('success', $this->lng->txt("settings_saved"), true);
1519  }
1520 
1521  $this->ctrl->redirect($this, "editRaters");
1522  }
1523 
1524  public function addSelfAppraiseeObject(): void
1525  {
1526  $ilUser = $this->user;
1527 
1528  if ($this->object->get360SelfAppraisee() &&
1529  !$this->object->isAppraisee($ilUser->getId())) {
1530  $this->object->addAppraisee($ilUser->getId());
1531  }
1532 
1533  $this->ctrl->redirect($this->parent_gui, "run");
1534  }
1535 
1536  public function initMailRatersForm(
1537  int $appr_id,
1538  array $rec_ids
1539  ): ilPropertyFormGUI {
1540  $form = new ilPropertyFormGUI();
1541  $form->setFormAction($this->ctrl->getFormAction($this, "mailRatersAction"));
1542  $form->setTitle($this->lng->txt('compose'));
1543 
1544  $all_data = $this->object->getRatersData($appr_id);
1545  $rec_data = array();
1546  foreach ($rec_ids as $rec_id) {
1547  if (isset($all_data[$rec_id])) {
1548  $rec_data[] = $all_data[$rec_id]["lastname"] . ", " .
1549  $all_data[$rec_id]["firstname"] .
1550  " (" . $all_data[$rec_id]["email"] . ")";
1551  }
1552  }
1553  sort($rec_data);
1554  $rec = new ilCustomInputGUI($this->lng->txt('recipients'));
1555  $rec->setHtml(implode("<br />", $rec_data));
1556  $form->addItem($rec);
1557 
1558  $subject = new ilTextInputGUI($this->lng->txt('subject'), 'subject');
1559  $subject->setSize(50);
1560  $subject->setRequired(true);
1561  $form->addItem($subject);
1562 
1563  $existingdata = $this->object->getExternalCodeRecipients();
1564  $existingcolumns = array();
1565  if (count($existingdata)) {
1566  $first = array_shift($existingdata);
1567  foreach ($first as $key => $value) {
1568  if (strcmp($key, 'code') !== 0 && strcmp($key, 'email') !== 0 && strcmp($key, 'sent') !== 0) {
1569  $existingcolumns[] = '[' . $key . ']';
1570  }
1571  }
1572  }
1573 
1574  $mailmessage_u = new ilTextAreaInputGUI($this->lng->txt('survey_360_rater_message_content_registered'), 'message_u');
1575  $mailmessage_u->setRequired(true);
1576  $mailmessage_u->setCols(80);
1577  $mailmessage_u->setRows(10);
1578  $form->addItem($mailmessage_u);
1579 
1580  $mailmessage_a = new ilTextAreaInputGUI($this->lng->txt('survey_360_rater_message_content_anonymous'), 'message_a');
1581  $mailmessage_a->setRequired(true);
1582  $mailmessage_a->setCols(80);
1583  $mailmessage_a->setRows(10);
1584  $mailmessage_a->setInfo(sprintf($this->lng->txt('message_content_info'), implode(', ', $existingcolumns)));
1585  $form->addItem($mailmessage_a);
1586 
1587  $recf = new ilHiddenInputGUI("rater_id");
1588  $recf->setValue(implode(";", $rec_ids));
1589  $form->addItem($recf);
1590 
1591  $form->addCommandButton("mailRatersAction", $this->lng->txt("send"));
1592  $form->addCommandButton("editRaters", $this->lng->txt("cancel"));
1593 
1594  $subject->setValue(sprintf($this->lng->txt('survey_360_rater_subject_default'), $this->object->getTitle()));
1595  $mailmessage_u->setValue($this->lng->txt('survey_360_rater_message_content_registered_default'));
1596  $mailmessage_a->setValue($this->lng->txt('survey_360_rater_message_content_anonymous_default'));
1597 
1598  return $form;
1599  }
1600 
1601  public function mailRatersObject(): void
1602  {
1603  $appr_id = $this->handleRatersAccess();
1604  $all_data = $this->object->getRatersData($appr_id);
1605  $this->ctrl->setParameter($this, "appr_id", $appr_id);
1606 
1607  $raters = $this->edit_request->getRaterIds();
1608 
1609  $rec = [];
1610  $external_rater = false;
1611  $rater_id = "";
1612  foreach ($raters as $id) {
1613  if (isset($all_data[$id])) {
1614  if ($all_data[$id]["login"] != "") {
1615  $rec[] = $all_data[$id]["login"];
1616  } elseif ($all_data[$id]["email"] != "") {
1617  $rec[] = $all_data[$id]["email"];
1618  $external_rater = true;
1619  $rater_id = $all_data[$id]["user_id"];
1620  }
1621  }
1622  }
1623  if ($external_rater && count($rec) > 1) {
1624  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("svy_only_max_one_external_rater"), true);
1625  $this->ctrl->redirect($this, "editRaters");
1626  }
1627 
1629 
1630  $contextParameters = [
1631  'ref_id' => $this->object->getRefId(),
1632  'ts' => time(),
1633  'appr_id' => $appr_id,
1634  'rater_id' => $rater_id,
1635  ilMailFormCall::CONTEXT_KEY => "svy_rater_inv"
1636  ];
1637 
1638  $this->ctrl->redirectToURL(ilMailFormCall::getRedirectTarget(
1639  $this,
1640  'editRaters',
1641  [
1642  'recipients' => base64_encode(json_encode($rec, JSON_THROW_ON_ERROR)),
1643  ],
1644  [
1645  'type' => 'new',
1646  'sig' => rawurlencode(base64_encode("\n\n" . $this->lng->txt("svy_link_to_svy") . ": {{SURVEY_LINK}}"))
1647  ],
1648  $contextParameters
1649  ));
1650  }
1651 
1652  public function mailRatersObjectOld(
1653  ?ilPropertyFormGUI $a_form = null
1654  ): void {
1655  $ilTabs = $this->tabs;
1656  $rater_ids = $this->edit_request->getRaterIds();
1657  if (!$a_form) {
1658  $appr_id = $this->handleRatersAccess();
1659  $this->ctrl->setParameter($this, "appr_id", $appr_id);
1660 
1661  if (count($rater_ids) === 0) {
1662  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("select_one"), true);
1663  $this->ctrl->redirect($this, "editRaters");
1664  }
1665 
1666  $a_form = $this->initMailRatersForm($appr_id, $rater_ids);
1667  }
1668 
1669  $ilTabs->clearTargets();
1670  $ilTabs->setBackTarget(
1671  $this->lng->txt("btn_back"),
1672  $this->ctrl->getLinkTarget($this, "editRaters")
1673  );
1674 
1675  $this->tpl->setContent($a_form->getHTML());
1676  }
1677 
1678  public function mailRatersActionObject(): void
1679  {
1680  $ilUser = $this->user;
1681  $appr_id = $this->handleRatersAccess();
1682  $this->ctrl->setParameter($this, "appr_id", $appr_id);
1683 
1684  $rec_ids = $this->edit_request->getRaterIds();
1685  if (count($rec_ids) === 0) {
1686  $this->ctrl->redirect($this, "editRaters");
1687  }
1688 
1689  $form = $this->initMailRatersForm($appr_id, $rec_ids);
1690  if ($form->checkInput()) {
1691  $txt_u = $form->getInput("message_u");
1692  $txt_a = $form->getInput("message_a");
1693  $subj = $form->getInput("subject");
1694 
1695  // #12743
1696  $sender_id = (trim($ilUser->getEmail()))
1697  ? $ilUser->getId()
1699 
1700  $all_data = $this->object->getRatersData($appr_id);
1701  foreach ($rec_ids as $rec_id) {
1702  if (isset($all_data[$rec_id])) {
1703  $user = $all_data[$rec_id];
1704 
1705  // anonymous
1706  if (strpos($rec_id, "a") === 0) {
1707  $mytxt = $txt_a;
1708  $url = $user["href"];
1709  $rcp = $user["email"];
1710  }
1711  // reg
1712  else {
1713  $mytxt = $txt_u;
1714  $user["code"] = $this->lng->txt("survey_code_mail_on_demand");
1715  $url = ilLink::_getStaticLink($this->object->getRefId());
1716  $rcp = $user["login"]; // #15141
1717  }
1718 
1719  $mytxt = str_replace(
1720  ["[lastname]", "[firstname]", "[url]", "[code]"],
1721  [$user["lastname"], $user["firstname"], $url, $user["code"]],
1722  $mytxt
1723  );
1724 
1725  $mail = new ilMail($sender_id);
1726  $mail->enqueue(
1727  $rcp, // to
1728  "", // cc
1729  "", // bcc
1730  $subj, // subject
1731  $mytxt, // message
1732  array() // attachments
1733  );
1734 
1735  $this->object->set360RaterSent(
1736  $appr_id,
1737  (strpos($rec_id, "a") === 0) ? 0 : (int) substr($rec_id, 1),
1738  (strpos($rec_id, "u") === 0) ? 0 : (int) substr($rec_id, 1)
1739  );
1740  }
1741  }
1742 
1743  $this->tpl->setOnScreenMessage('success', $this->lng->txt("mail_sent"), true);
1744  $this->ctrl->redirect($this, "editRaters");
1745  }
1746 
1747  $form->setValuesByPost();
1748  $this->mailRatersObject();
1749  }
1750 
1751  public function confirmAppraiseeCloseObject(): void
1752  {
1753  $ilUser = $this->user;
1754  $tpl = $this->tpl;
1755  $ilTabs = $this->tabs;
1756 
1757  $ilTabs->clearTargets();
1758  $ilTabs->setBackTarget(
1759  $this->lng->txt("menuback"),
1760  $this->ctrl->getLinkTarget($this->parent_gui, "run")
1761  );
1762 
1763  if (!$this->object->isAppraisee($ilUser->getId())) {
1764  $this->ctrl->redirect($this->parent_gui, "run");
1765  }
1766 
1767  $cgui = new ilConfirmationGUI();
1768  $cgui->setHeaderText($this->lng->txt("survey_360_sure_appraisee_close"));
1769 
1770  $cgui->setFormAction($this->ctrl->getFormAction($this, "appraiseeClose"));
1771  $cgui->setCancel($this->lng->txt("cancel"), "confirmAppraiseeCloseCancel");
1772  $cgui->setConfirm($this->lng->txt("confirm"), "appraiseeClose");
1773 
1774  $tpl->setContent($cgui->getHTML());
1775  }
1776 
1777  public function confirmAppraiseeCloseCancelObject(): void
1778  {
1779  $this->ctrl->redirect($this->parent_gui, "run");
1780  }
1781 
1782  public function appraiseeCloseObject(): void
1783  {
1784  $ilUser = $this->user;
1785 
1786  if (!$this->object->isAppraisee($ilUser->getId())) {
1787  $this->ctrl->redirect($this->parent_gui, "run");
1788  }
1789 
1790  $this->object->closeAppraisee($ilUser->getId());
1791  $this->tpl->setOnScreenMessage('success', $this->lng->txt("survey_360_appraisee_close_action_success"), true);
1792  $this->ctrl->redirect($this->parent_gui, "run");
1793  }
1794 
1795  public function confirmAdminAppraiseesCloseObject(): void
1796  {
1797  $tpl = $this->tpl;
1798 
1799  $this->handleWriteAccess();
1800 
1801  $appr_ids = $this->edit_request->getAppraiseeIds();
1802 
1803  if (count($appr_ids) === 0) {
1804  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("select_one"), true);
1805  $this->ctrl->redirect($this, "listAppraisees");
1806  }
1807 
1808  $cgui = new ilConfirmationGUI();
1809  $cgui->setHeaderText($this->lng->txt("survey_360_sure_appraisee_close_admin"));
1810 
1811  $cgui->setFormAction($this->ctrl->getFormAction($this, "adminAppraiseesClose"));
1812  $cgui->setCancel($this->lng->txt("cancel"), "listAppraisees");
1813  $cgui->setConfirm($this->lng->txt("confirm"), "adminAppraiseesClose");
1814 
1815  foreach ($appr_ids as $appr_id) {
1816  $cgui->addItem("appr_id[]", $appr_id, ilUserUtil::getNamePresentation($appr_id));
1817  }
1818 
1819  $tpl->setContent($cgui->getHTML());
1820  }
1821 
1822  public function adminAppraiseesCloseObject(): void
1823  {
1824  $this->handleWriteAccess();
1825 
1826  $appr_ids = $this->edit_request->getAppraiseeIds();
1827 
1828  if (count($appr_ids) === 0) {
1829  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("select_one"), true);
1830  $this->ctrl->redirect($this, "listAppraisees");
1831  }
1832 
1833  $appr_data = $this->object->getAppraiseesData();
1834  foreach ($appr_ids as $appr_id) {
1835  if (isset($appr_data[$appr_id]) && !$appr_data[$appr_id]["closed"]) {
1836  $this->object->closeAppraisee($appr_id);
1837  }
1838  }
1839 
1840  $this->tpl->setOnScreenMessage('success', $this->lng->txt("survey_360_appraisee_close_action_success_admin"), true);
1841  $this->ctrl->redirect($this, "listAppraisees");
1842  }
1843 
1844  protected function listParticipantsObject(): void
1845  {
1846  $ilToolbar = $this->toolbar;
1847 
1848  if (!$this->isAnonymousListActive()) {
1849  $this->ctrl->redirect($this, "maintenance");
1850  }
1851 
1852  $this->handleWriteAccess();
1853  $this->setParticipantSubTabs("anon_participants");
1854 
1855  $this->gui->button(
1856  $this->lng->txt("print"),
1857  "#"
1858  )->onClick("window.print(); return false;")->toToolbar();
1859 
1860  $tbl = new ilSurveyParticipantsTableGUI($this, "listParticipants", $this->object);
1861  $this->tpl->setContent($tbl->getHTML());
1862  }
1863 
1868  public function inviteUsers(array $user_ids): void
1869  {
1870  $lng = $this->lng;
1871  $ctrl = $this->ctrl;
1872 
1873  foreach ($user_ids as $user_id) {
1874  $this->invitation_manager->add($this->object->getSurveyId(), $user_id);
1875  }
1876  $this->tpl->setOnScreenMessage('success', $lng->txt("svy_users_invited"), true);
1877  $ctrl->redirect($this, "maintenance");
1878  }
1879 }
importAccessCodesObject()
Import codes from export codes file (upload form)
Class ilSurveyParticipantsGUI.
setData(array $a_data)
codesObject()
Display the survey access codes tab.
const ANONYMOUS_USER_ID
Definition: constants.php:27
writePref(string $a_keyword, string $a_value)
This class represents a selection list property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
exportAllCodesObject()
Exports all survey codes.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
write(string $message, $level=ilLogLevel::INFO, array $context=[])
write log message
This class represents a file property in a property form.
maintenanceObject()
Participants maintenance.
setContent(string $a_html)
Sets content for standard template.
addCodeForExternal(string $email, string $lastname, string $firstname)
Add code for an external rater.
$url
Definition: shib_logout.php:68
setCodeLanguageObject()
Change survey language for direct access URL&#39;s.
setOptions(array $a_options)
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...
static subStr(string $a_str, int $a_start, ?int $a_length=null)
Definition: class.ilStr.php:21
Participants InvitationsManager $invitation_manager
static deliverData(string $a_data, string $a_filename, string $mime="application/octet-stream")
This class represents a email property in a property form.
mailRatersObjectOld(?ilPropertyFormGUI $a_form=null)
cancelDeleteSelectedUserDataObject()
Cancels the deletion of all user data.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
sort()
description: > Example for rendering a Sort Glyph.
Definition: sort.php:41
static getASCIIFilename(string $a_filename)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
ilObjSurveyGUI: ilSurveyEvaluationGUI, ilSurveyExecutionGUI ilObjSurveyGUI: ilObjectMetaDataGUI, ilPermissionGUI ilObjSurveyGUI: ilInfoScreenGUI, ilObjectCopyGUI ilObjSurveyGUI: ilSurveySkillDeterminationGUI ilObjSurveyGUI: ilCommonActionDispatcherGUI, ilSurveySkillGUI ilObjSurveyGUI: ilSurveyEditorGUI, ilSurveyConstraintsGUI ilObjSurveyGUI: ilSurveyParticipantsGUI, ilLearningProgressGUI ilObjSurveyGUI: ilExportGUI, ilLTIProviderObjectSettingGUI ilObjSurveyGUI: ILIAS
This class represents a hidden form property in a property form.
cancelDeleteAllUserDataObject()
Cancels delete of all user data in maintenance.
addSubTab(string $a_id, string $a_text, string $a_link, string $a_frame="")
static getNamePresentation( $a_user_id, bool $a_user_image=false, bool $a_profile_link=false, string $a_profile_back_link='', bool $a_force_first_lastname=false, bool $a_omit_login=false, bool $a_sortable=true, bool $a_return_data_array=false, $a_ctrl_path='ilpublicuserprofilegui')
Default behaviour is:
redirect(object $a_gui_obj, ?string $a_cmd=null, ?string $a_anchor=null, bool $is_async=false)
ILIAS Survey InternalGUIService $gui
deleteCodesObject()
Delete a list of survey codes.
global $DIC
Definition: shib_login.php:26
ILIAS Survey Editing EditManager $edit_manager
ILIAS Survey InternalService $survey_service
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
clearTargets()
clear all targets
initMailRatersForm(int $appr_id, array $rec_ids)
setRequired(bool $a_required)
ILIAS Survey InternalDataService $data_manager
$lang
Definition: xapiexit.php:25
createSurveyCodesObject()
Create access codes for the survey.
confirmDeleteSelectedUserDataObject()
Deletes all user data for the test object.
final const string CONTEXT_KEY
static setRecipients(array $recipients, string $type='to')
static fillAutoCompleteToolbar(object $parent_object, ?ilToolbarGUI $toolbar=null, array $a_options=[], bool $a_sticky=false)
array( auto_complete_name = $lng->txt(&#39;user&#39;), auto_complete_size = 15, user_type = array(ilCoursePar...
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
__construct(Container $dic, ilPlugin $plugin)
importAccessCodesActionObject()
Import codes from export codes file.
This class represents a text area property in a property form.
addExternalRaterFormObject(?ilPropertyFormGUI $a_form=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getRedirectTarget( $gui, string $cmd, array $gui_params=[], array $mail_params=[], array $context_params=[])
confirmDeleteAllUserDataObject()
Deletes all user data of the survey after confirmation.
_convertCharset(string $a_string, string $a_from_charset="", string $a_to_charset="UTF-8")
filterSurveyParticipantsByAccess(?array $a_finished_ids=null)
ILIAS Survey Mode FeatureConfig $feature_config
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
exportCodesObject()
Exports a list of survey codes.
deleteSingleUserResultsObject()
Asks for a confirmation to delete selected user data.
deleteAllUserDataObject()
Creates a confirmation form for delete all user data.
ILIAS Survey Code CodeManager $code_manager
ILIAS Survey Editing EditingGUIRequest $edit_request