ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilSurveyEvaluationGUI.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
16 {
20  protected $tabs;
21 
25  protected $access;
26 
30  protected $user;
31 
35  protected $rbacsystem;
36 
40  protected $tree;
41 
45  protected $toolbar;
46 
47  const TYPE_XLS = "excel";
48  const TYPE_SPSS = "csv";
49 
50  const EXCEL_SUBTITLE = "DDDDDD";
51 
52  public $object;
53  public $lng;
54  public $tpl;
55  public $ctrl;
56  public $appr_id = null;
57 
66  public function __construct($a_object)
67  {
68  global $DIC;
69 
70  $this->tabs = $DIC->tabs();
71  $this->access = $DIC->access();
72  $this->user = $DIC->user();
73  $this->rbacsystem = $DIC->rbac()->system();
74  $this->tree = $DIC->repositoryTree();
75  $this->toolbar = $DIC->toolbar();
76  $this->ui = $DIC->ui();
77  $lng = $DIC->language();
78  $tpl = $DIC["tpl"];
79  $ilCtrl = $DIC->ctrl();
80 
81  $this->lng = $lng;
82  $this->tpl = $tpl;
83  $this->ctrl = $ilCtrl;
84  $this->object = $a_object;
85  $this->log = ilLoggerFactory::getLogger("svy");
86  $this->array_panels = array();
87 
88  if ($this->object->get360Mode() || $this->object->getMode() == ilObjSurvey::MODE_SELF_EVAL) {
89  $this->determineAppraiseeId();
90  }
91  }
92 
96  public function executeCommand()
97  {
98  $skmg_set = new ilSkillManagementSettings();
99  if ($this->object->getSkillService() && $skmg_set->isActivated()) {
100  $cmd = $this->ctrl->getCmd("competenceEval");
101  } else {
102  $cmd = $this->ctrl->getCmd("evaluation");
103  }
104 
105  $next_class = $this->ctrl->getNextClass($this);
106 
107  $cmd = $this->getCommand($cmd);
108 
109  $this->log->debug($cmd);
110 
111  switch ($next_class) {
112  default:
113  $this->setEvalSubTabs();
114  $ret = &$this->$cmd();
115  break;
116  }
117  return $ret;
118  }
119 
120  public function getCommand($cmd)
121  {
122  return $cmd;
123  }
124 
130  public function setEvalSubtabs()
131  {
132  $ilTabs = $this->tabs;
133  $ilAccess = $this->access;
134 
135  $skmg_set = new ilSkillManagementSettings();
136  if ($this->object->getSkillService() && $skmg_set->isActivated()) {
137  $ilTabs->addSubTabTarget(
138  "svy_eval_competences",
139  $this->ctrl->getLinkTarget($this, "competenceEval"),
140  array("competenceEval")
141  );
142  }
143 
144  $ilTabs->addSubTabTarget(
145  "svy_eval_cumulated",
146  $this->ctrl->getLinkTarget($this, "evaluation"),
147  array("evaluation", "checkEvaluationAccess")
148  );
149 
150  $ilTabs->addSubTabTarget(
151  "svy_eval_detail",
152  $this->ctrl->getLinkTarget($this, "evaluationdetails"),
153  array("evaluationdetails")
154  );
155 
156  if ($this->hasResultsAccess()) {
157  $ilTabs->addSubTabTarget(
158  "svy_eval_user",
159  $this->ctrl->getLinkTarget($this, "evaluationuser"),
160  array("evaluationuser")
161  );
162  }
163  }
164 
165 
171  public function setAppraiseeId($a_val)
172  {
173  $this->appr_id = $a_val;
174  }
175 
181  public function getAppraiseeId()
182  {
183  return $this->appr_id;
184  }
185 
189  public function determineAppraiseeId()
190  {
193 
194  $appr_id = "";
195 
196  // always start with current user
197  if ($_REQUEST["appr_id"] == "") {
198  $req_appr_id = $ilUser->getId();
199  } else {
200  $req_appr_id = (int) $_REQUEST["appr_id"];
201  }
202 
203  // write access? allow selection
204  if ($req_appr_id > 0 && $this->object->get360Mode()) {
205  $all_appr = ($this->object->get360Results() == ilObjSurvey::RESULTS_360_ALL);
206 
207  $valid = array();
208  foreach ($this->object->getAppraiseesData() as $item) {
209  if ($item["closed"] &&
210  ($item["user_id"] == $ilUser->getId() ||
211  $rbacsystem->checkAccess("write", $this->object->getRefId()) ||
212  $all_appr)) {
213  $valid[] = $item["user_id"];
214  }
215  }
216  if (in_array($req_appr_id, $valid)) {
217  $appr_id = $req_appr_id;
218  } else {
219  // current selection / user is not valid, use 1st valid instead
220  $appr_id = array_shift($valid);
221  }
222  } else { // SVY SELF EVALUATION MODE
223  $appr_id = $req_appr_id;
224  }
225 
226  $this->ctrl->setParameter($this, "appr_id", $appr_id);
227  $this->setAppraiseeId($appr_id);
228  }
229 
230 
239  {
241 
242  if ($this->object->getAnonymize() == 1 &&
243  $_SESSION["anon_evaluation_access"] == $_GET["ref_id"]) {
244  return true;
245  }
246 
248  if ($this->object->getAnonymize() == 1) {
249  $_SESSION["anon_evaluation_access"] = $_GET["ref_id"];
250  }
251  return true;
252  }
253 
254  if ($this->object->getAnonymize() == 1) {
255  // autocode
256  $surveycode = $this->object->getUserAccessCode($ilUser->getId());
257  if ($this->object->isAnonymizedParticipant($surveycode)) {
258  $_SESSION["anon_evaluation_access"] = $_GET["ref_id"];
259  return true;
260  }
261 
262  /* try to find code for current (registered) user from existing run
263  if($this->object->findCodeForUser($ilUser->getId()))
264  {
265  $_SESSION["anon_evaluation_access"] = $_GET["ref_id"];
266  return true;
267  }
268  */
269 
270  // code needed
271  $this->tpl->setVariable("TABS", "");
272  $this->tpl->addBlockFile("ADM_CONTENT", "adm_content", "tpl.il_svy_svy_evaluation_checkaccess.html", "Modules/Survey");
273  $this->tpl->setCurrentBlock("adm_content");
274  $this->tpl->setVariable("AUTHENTICATION_NEEDED", $this->lng->txt("svy_check_evaluation_authentication_needed"));
275  $this->tpl->setVariable("FORM_ACTION", $this->ctrl->getFormAction($this, "checkEvaluationAccess"));
276  $this->tpl->setVariable("EVALUATION_CHECKACCESS_INTRODUCTION", $this->lng->txt("svy_check_evaluation_access_introduction"));
277  $this->tpl->setVariable("VALUE_CHECK", $this->lng->txt("ok"));
278  $this->tpl->setVariable("VALUE_CANCEL", $this->lng->txt("cancel"));
279  $this->tpl->setVariable("TEXT_SURVEY_CODE", $this->lng->txt("survey_code"));
280  $this->tpl->parseCurrentBlock();
281  }
282 
283  $_SESSION["anon_evaluation_access"] = null;
284  return false;
285  }
286 
294  public function checkEvaluationAccess()
295  {
296  $surveycode = $_POST["surveycode"];
297  if ($this->object->isAnonymizedParticipant($surveycode)) {
298  $_SESSION["anon_evaluation_access"] = $_GET["ref_id"];
299  $this->evaluation();
300  } else {
301  ilUtil::sendFailure($this->lng->txt("svy_check_evaluation_wrong_key", true));
302  $this->cancelEvaluationAccess();
303  }
304  }
305 
313  public function cancelEvaluationAccess()
314  {
316  $tree = $this->tree;
317  $path = $tree->getPathFull($this->object->getRefID());
318  $ilCtrl->setParameterByClass(
319  "ilrepositorygui",
320  "ref_id",
321  $path[count($path) - 2]["child"]
322  );
323  $ilCtrl->redirectByClass("ilrepositorygui", "frameset");
324  }
325 
333  public function evaluationdetails()
334  {
335  $this->evaluation(1);
336  }
337 
338  public function exportCumulatedResults($details = 0)
339  {
340  $finished_ids = null;
341  if ($this->object->get360Mode()) {
342  $appr_id = $_REQUEST["appr_id"];
343  if (!$appr_id) {
344  $this->ctrl->redirect($this, $details ? "evaluationdetails" : "evaluation");
345  }
346  $finished_ids = $this->object->getFinishedIdsForAppraiseeId($appr_id);
347  if (!sizeof($finished_ids)) {
348  $finished_ids = array(-1);
349  }
350  }
351 
352  // titles
353  $title_row = array();
354  $do_title = $do_label = true;
355  switch ($_POST['export_label']) {
356  case 'label_only':
357  $title_row[] = $this->lng->txt("label");
358  $do_title = false;
359  break;
360 
361  case 'title_only':
362  $title_row[] = $this->lng->txt("title");
363  $do_label = false;
364  break;
365 
366  default:
367  $title_row[] = $this->lng->txt("title");
368  $title_row[] = $this->lng->txt("label");
369  break;
370  }
371  $title_row[] = $this->lng->txt("question");
372  $title_row[] = $this->lng->txt("question_type");
373  $title_row[] = $this->lng->txt("users_answered");
374  $title_row[] = $this->lng->txt("users_skipped");
375  $title_row[] = $this->lng->txt("mode");
376  $title_row[] = $this->lng->txt("mode_text");
377  $title_row[] = $this->lng->txt("mode_nr_of_selections");
378  $title_row[] = $this->lng->txt("median");
379  $title_row[] = $this->lng->txt("arithmetic_mean");
380 
381  // creating container
382  switch ($_POST["export_format"]) {
383  case self::TYPE_XLS:
384  $excel = new ilExcel();
385  $excel->addSheet($this->lng->txt("svy_eval_cumulated"));
386  $excel->setCellArray(array($title_row), "A1");
387  $excel->setBold("A1:" . $excel->getColumnCoord(sizeof($title_row) - 1) . "1");
388  break;
389 
390  case self::TYPE_SPSS:
391  $csvfile = array($title_row);
392  break;
393  }
394 
395 
396  // parse answer data in evaluation results
397  $ov_row = 2;
398  foreach ($this->object->getSurveyQuestions() as $qdata) {
399  $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($qdata["question_id"], $finished_ids);
400  $q_res = $q_eval->getResults();
401  $ov_rows = $q_eval->exportResults($q_res, $do_title, $do_label);
402 
403  switch ($_POST["export_format"]) {
404  case self::TYPE_XLS:
405  $excel->setActiveSheet(0);
406  foreach ($ov_rows as $row) {
407  foreach ($row as $col => $value) {
408  $excel->setCell($ov_row, $col, $value);
409  }
410  $ov_row++;
411  }
412  break;
413 
414  case self::TYPE_SPSS:
415  foreach ($ov_rows as $row) {
416  $csvfile[] = $row;
417  }
418  break;
419  }
420 
421  if ($details) {
422  switch ($_POST["export_format"]) {
423  case self::TYPE_XLS:
424  $this->exportResultsDetailsExcel($excel, $q_eval, $q_res, $do_title, $do_label);
425  break;
426  }
427  }
428  }
429 
430  // #11179
431  $type = !$details
432  ? $this->lng->txt("svy_eval_cumulated")
433  : $this->lng->txt("svy_eval_detail");
434 
435  $surveyname = $this->object->getTitle() . " " . $type . " " . date("Y-m-d");
436  $surveyname = preg_replace("/\s/", "_", trim($surveyname));
437  $surveyname = ilUtil::getASCIIFilename($surveyname);
438 
439  // send to client
440  switch ($_POST["export_format"]) {
441  case self::TYPE_XLS:
442  $excel->sendToClient($surveyname);
443  break;
444 
445  case self::TYPE_SPSS:
446  $csv = "";
447  $separator = ";";
448  foreach ($csvfile as $csvrow) {
449  $csvrow = $this->processCSVRow($csvrow, true, $separator);
450  $csv .= join($separator, $csvrow) . "\n";
451  }
452  ilUtil::deliverData($csv, $surveyname . ".csv");
453  exit();
454  break;
455  }
456  }
457 
467  protected function exportResultsDetailsExcel(ilExcel $a_excel, SurveyQuestionEvaluation $a_eval, $a_results, $a_do_title, $a_do_label)
468  {
469  $question_res = $a_results;
470  $matrix = false;
471  if (is_array($question_res)) {
472  $question_res = $question_res[0][1];
473  $matrix = true;
474  }
475  $question = $question_res->getQuestion();
476 
477  $a_excel->addSheet($question->getTitle());
478 
479 
480  // question "overview"
481 
482  $kv = array();
483 
484  if ($a_do_title) {
485  $kv[$this->lng->txt("title")] = $question->getTitle();
486  }
487  if ($a_do_label) {
488  $kv[$this->lng->txt("label")] = $question->label;
489  }
490 
491  // question
492  $kv[$this->lng->txt("question")] = $question->getQuestiontext();
493 
494  // question type
495  $kv[$this->lng->txt("question_type")] = SurveyQuestion::_getQuestionTypeName($question->getQuestionType());
496 
497  // :TODO: present subtypes (hrz/vrt, mc/sc mtx, metric scale)?
498 
499  // answered and skipped users
500  $kv[$this->lng->txt("users_answered")] = (int) $question_res->getUsersAnswered();
501  $kv[$this->lng->txt("users_skipped")] = (int) $question_res->getUsersSkipped(); // #0021671
502 
503  $excel_row = 1;
504 
505  foreach ($kv as $key => $value) {
506  $a_excel->setCell($excel_row, 0, $key);
507  $a_excel->setCell($excel_row++, 1, $value);
508  }
509 
510  if (!$matrix) {
511  $this->parseResultsToExcel(
512  $a_excel,
513  $question_res,
514  $excel_row,
515  $a_eval->getExportGrid($a_results),
516  $a_eval->getTextAnswers($a_results)
517  );
518  } else {
519  // question
520  $this->parseResultsToExcel(
521  $a_excel,
522  $question_res,
523  $excel_row,
524  null,
525  null,
526  false
527  );
528 
529  $texts = $a_eval->getTextAnswers($a_results);
530 
531  // "rows"
532  foreach ($a_results as $row_results) {
533  $row_title = $row_results[0];
534 
535  $a_excel->setCell($excel_row, 0, $this->lng->txt("row"));
536  $a_excel->setCell($excel_row++, 1, $row_title);
537 
538  $this->parseResultsToExcel(
539  $a_excel,
540  $row_results[1],
541  $excel_row,
542  $a_eval->getExportGrid($row_results[1]),
543  is_array($texts[$row_title])
544  ? array("" => $texts[$row_title])
545  : null
546  );
547  }
548  }
549 
550  // matrix question: overview #21438
551  if ($matrix) {
552  $a_excel->setCell($excel_row++, 0, $this->lng->txt("overview"));
553 
554  // title row with variables
555  $counter = 0;
556  $cats = $question->getColumns();
557  foreach ($cats->getCategories() as $cat) {
558  $a_excel->setColors($a_excel->getCoordByColumnAndRow(1 + $counter, $excel_row), ilSurveyEvaluationGUI::EXCEL_SUBTITLE);
559  $a_excel->setCell($excel_row, 1 + $counter, $cat->title);
560  $counter++;
561  }
562  $excel_row++;
563 
564  foreach ($a_results as $row_results) {
565  $row_title = $row_results[0];
566  $counter = 0;
567  $a_excel->setCell($excel_row, 0, $row_title);
568 
569  $vars = $row_results[1]->getVariables();
570  if ($vars) {
571  foreach ($vars as $var) {
572  $a_excel->setCell($excel_row, ++$counter, $var->abs);
573  }
574  }
575  $excel_row++;
576  }
577  }
578 
579  // 1st column is bold
580  $a_excel->setBold("A1:A" . $excel_row);
581  }
582 
583  protected function parseResultsToExcel(ilExcel $a_excel, ilSurveyEvaluationResults $a_results, &$a_excel_row, array $a_grid = null, array $a_text_answers = null, $a_include_mode = true)
584  {
585  $kv = array();
586 
587  if ($a_include_mode) {
588  if ($a_results->getModeValue() !== null) {
589  // :TODO:
590  $kv[$this->lng->txt("mode")] = is_array($a_results->getModeValue())
591  ? implode(", ", $a_results->getModeValue())
592  : $a_results->getModeValue();
593 
594  $kv[$this->lng->txt("mode_text")] = $a_results->getModeValueAsText();
595  $kv[$this->lng->txt("mode_nr_of_selections")] = (int) $a_results->getModeNrOfSelections();
596  }
597 
598  if ($a_results->getMedian() !== null) {
599  $kv[$this->lng->txt("median")] = $a_results->getMedianAsText();
600  }
601 
602  if ($a_results->getMean() !== null) {
603  $kv[$this->lng->txt("arithmetic_mean")] = $a_results->getMean();
604  }
605  }
606 
607  foreach ($kv as $key => $value) {
608  $a_excel->setCell($a_excel_row, 0, $key);
609  $a_excel->setCell($a_excel_row++, 1, $value);
610  }
611 
612  // grid
613  if ($a_grid) {
614  // header
615  $a_excel->setColors("B" . $a_excel_row . ":E" . $a_excel_row, ilSurveyEvaluationGUI::EXCEL_SUBTITLE);
616  $a_excel->setCell($a_excel_row, 0, $this->lng->txt("categories"));
617  foreach ($a_grid["cols"] as $col_idx => $col) {
618  $a_excel->setCell($a_excel_row, $col_idx + 1, $col);
619  }
620  $a_excel_row++;
621 
622  // rows
623  foreach ($a_grid["rows"] as $cols) {
624  foreach ($cols as $col_idx => $col) {
625  $a_excel->setCell($a_excel_row, $col_idx + 1, $col);
626  }
627  $a_excel_row++;
628  }
629  }
630 
631  // text answers
632  if ($a_text_answers) {
633  // "given_answers" ?
634  $a_excel->setCell($a_excel_row, 0, $this->lng->txt("freetext_answers"));
635 
636  // mc/sc
637  if (!is_array($a_text_answers[""])) {
638  $a_excel->setColors("B" . $a_excel_row . ":C" . $a_excel_row, ilSurveyEvaluationGUI::EXCEL_SUBTITLE);
639  $a_excel->setCell($a_excel_row, 1, $this->lng->txt("title"));
640  $a_excel->setCell($a_excel_row++, 2, $this->lng->txt("answer"));
641  }
642  // mtx (row), txt
643  else {
644  $a_excel->setColors("B" . $a_excel_row . ":B" . $a_excel_row, ilSurveyEvaluationGUI::EXCEL_SUBTITLE);
645  $a_excel->setCell($a_excel_row++, 1, $this->lng->txt("answer"));
646  }
647 
648  foreach ($a_text_answers as $var => $items) {
649  foreach ($items as $item) {
650  if (!is_array($a_text_answers[""])) {
651  $a_excel->setCell($a_excel_row, 1, $var);
652  $a_excel->setCell($a_excel_row++, 2, $item);
653  } else {
654  $a_excel->setCell($a_excel_row++, 1, $item);
655  }
656  }
657  }
658  }
659  }
660 
661  public function exportData()
662  {
663  if (strlen($_POST["export_format"])) {
664  $this->exportCumulatedResults(0);
665  return;
666  } else {
667  $this->ctrl->redirect($this, 'evaluation');
668  }
669  }
670 
671  public function exportDetailData()
672  {
673  if (strlen($_POST["export_format"])) {
674  $this->exportCumulatedResults(1);
675  return;
676  } else {
677  $this->ctrl->redirect($this, 'evaluation');
678  }
679  }
680 
681  public function printEvaluation()
682  {
683  ilUtil::sendInfo($this->lng->txt('use_browser_print_function'), true);
684  $this->ctrl->redirect($this, 'evaluation');
685  }
686 
687  protected function buildExportModal($a_id, $a_cmd)
688  {
689  $tpl = $this->tpl;
690 
691  $form_id = "svymdfrm";
692 
693  // hide modal on form submit
694  $tpl->addOnLoadCode('$("#form_' . $form_id . '").submit(function() { $("#' . $a_id . '").modal("hide"); });');
695 
696  $modal = ilModalGUI::getInstance();
697  $modal->setId($a_id);
698  $modal->setHeading(($this->lng->txt("svy_export_format")));
699 
700  $form = new ilPropertyFormGUI();
701  $form->setId($form_id);
702  $form->setFormAction($this->ctrl->getFormAction($this, $a_cmd));
703 
704  $format = new ilSelectInputGUI($this->lng->txt("filetype"), "export_format");
705  $format->setOptions(array(
706  self::TYPE_XLS => $this->lng->txt('exp_type_excel'),
707  self::TYPE_SPSS => $this->lng->txt('exp_type_csv')
708  ));
709  $form->addItem($format, true);
710 
711  $label = new ilSelectInputGUI($this->lng->txt("title"), "export_label");
712  $label->setOptions(array(
713  'label_only' => $this->lng->txt('export_label_only'),
714  'title_only' => $this->lng->txt('export_title_only'),
715  'title_label' => $this->lng->txt('export_title_label')
716  ));
717  $form->addItem($label);
718 
719  $form->addCommandButton($a_cmd, $this->lng->txt("export"));
720  $form->setPreventDoubleSubmission(false);
721 
722  $modal->setBody($form->getHTML());
723 
724  return $modal->getHTML();
725  }
726 
727  public function evaluation($details = 0, $pdf = false, $return_pdf = false)
728  {
730  $ilToolbar = $this->toolbar;
731  $tree = $this->tree;
732  $ui = $this->ui;
733 
734  $ui_factory = $ui->factory();
735  $ui_renderer = $ui->renderer();
736 
737  $this->log->debug("check access");
738 
739  // auth
740  if (!$this->hasResultsAccess()) {
741  if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
742  ilUtil::sendFailure($this->lng->txt("permission_denied"));
743  return;
744  }
745 
746  switch ($this->object->getEvaluationAccess()) {
748  ilUtil::sendFailure($this->lng->txt("permission_denied"));
749  return;
750 
753  if (!$this->checkAnonymizedEvaluationAccess()) {
754  ilUtil::sendFailure($this->lng->txt("permission_denied"));
755  return;
756  }
757  break;
758  }
759  }
760 
761  $this->log->debug("check access ok");
762 
763  if (!$pdf) {
764  $ilToolbar->setFormAction($this->ctrl->getFormAction($this));
765  }
766 
767  $this->tpl->addBlockFile("ADM_CONTENT", "adm_content", "tpl.il_svy_svy_evaluation.html", "Modules/Survey");
768 
769  if ($this->object->get360Mode()) {
770  $appr_id = $this->getAppraiseeId();
771  $this->addApprSelectionToToolbar();
772  }
773 
774  $results = array();
775  if (!$this->object->get360Mode() || $appr_id) {
776  if ($details) {
777  $captions = new ilSelectInputGUI($this->lng->txt("svy_eval_captions"), "cp");
778  $captions->setOptions(array(
779  "ap" => $this->lng->txt("svy_eval_captions_abs_perc"),
780  "a" => $this->lng->txt("svy_eval_captions_abs"),
781  "p" => $this->lng->txt("svy_eval_captions_perc")
782  ));
783  $captions->setValue($_POST["cp"]);
784  $ilToolbar->addInputItem($captions, true);
785 
786  $view = new ilSelectInputGUI($this->lng->txt("svy_eval_view"), "vw");
787  $view->setOptions(array(
788  "tc" => $this->lng->txt("svy_eval_view_tables_charts"),
789  "t" => $this->lng->txt("svy_eval_view_tables"),
790  "c" => $this->lng->txt("svy_eval_view_charts")
791  ));
792  $view->setValue($_POST["vw"]);
793  $ilToolbar->addInputItem($view, true);
794 
795  $button = ilSubmitButton::getInstance();
796  $button->setCaption("ok");
797  $button->setCommand("evaluationdetails");
798  $button->setOmitPreventDoubleSubmission(true);
799  $ilToolbar->addButtonInstance($button);
800 
801  $ilToolbar->addSeparator();
802 
803  //templates: results, table of contents
804  $dtmpl = new ilTemplate("tpl.il_svy_svy_results_details.html", true, true, "Modules/Survey");
805  $toc_tpl = new ilTemplate("tpl.svy_results_table_contents.html", true, true, "Modules/Survey");
806  $this->lng->loadLanguageModule("content");
807  $toc_tpl->setVariable("TITLE_TOC", $this->lng->txt('cont_toc'));
808  }
809 
810  if (!$pdf) {
811  $modal_id = "svy_ev_exp";
812  $modal = $this->buildExportModal($modal_id, $details
813  ? 'exportDetailData'
814  : 'exportData');
815 
816  $button = ilLinkButton::getInstance();
817  $button->setCaption("export");
818  $button->setOnClick('$(\'#' . $modal_id . '\').modal(\'show\')');
819  $ilToolbar->addButtonInstance($button);
820 
821  $ilToolbar->addSeparator();
822 
823  $button = ilLinkButton::getInstance();
824  $button->setCaption("print");
825  $button->setOnClick("if(il.Accordion) { il.Accordion.preparePrint(); } window.print(); return false;");
826  $button->setOmitPreventDoubleSubmission(true);
827  $ilToolbar->addButtonInstance($button);
828 
829  // patch BGHW jluetzen-ilias
830  $this->ctrl->setParameter($this, "cp", $_POST["cp"]);
831  $this->ctrl->setParameter($this, "vw", $_POST["vw"]);
832  $url = $this->ctrl->getLinkTarget($this, $details
833  ? "evaluationdetailspdf"
834  : "evaluationpdf");
835  $this->ctrl->setParameter($this, "cp", "");
836  $this->ctrl->setParameter($this, "vw", "");
837  $button = ilLinkButton::getInstance();
838  $button->setCaption("svy_export_pdf");
839  $button->setUrl($url);
840  $button->setOmitPreventDoubleSubmission(true);
841  $ilToolbar->addButtonInstance($button);
842  }
843 
844  $finished_ids = null;
845  if ($appr_id) {
846  $finished_ids = $this->object->getFinishedIdsForAppraiseeId($appr_id);
847  if (!sizeof($finished_ids)) {
848  $finished_ids = array(-1);
849  }
850  }
851 
852  $details_figure = $_POST["cp"]
853  ? $_POST["cp"]
854  : "ap";
855  $details_view = $_POST["vw"]
856  ? $_POST["vw"]
857  : "tc";
858 
859  // @todo
860  // filter finished ids
861  $finished_ids2 = $this->access->filterUserIdsByRbacOrPositionOfCurrentUser(
862  'read_results',
863  'access_results',
864  $this->object->getRefId(),
865  (array) $finished_ids
866  );
867 
868  // parse answer data in evaluation results
869  $list = new ilNestedList();
870 
871  foreach ($this->object->getSurveyQuestions() as $qdata) {
872  $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($qdata["question_id"], $finished_ids);
873  $q_res = $q_eval->getResults();
874  $results[] = $q_res;
875 
876  if ($details) {
877  //$this->renderDetails($details_view, $details_figure, $dtmpl, $qdata, $q_eval, $q_res);
878  $this->renderDetails($details_view, $details_figure, $qdata, $q_eval, $q_res, $pdf);
879 
880  // TABLE OF CONTENTS
881  if ($qdata["questionblock_id"] &&
882  $qdata["questionblock_id"] != $this->last_questionblock_id) {
883  $qblock = ilObjSurvey::_getQuestionblock($qdata["questionblock_id"]);
884  if ($qblock["show_blocktitle"]) {
885  $list->addListNode($qdata["questionblock_title"], "q" . $qdata["questionblock_id"]);
886  } else {
887  $list->addListNode("", "q" . $qdata["questionblock_id"]);
888  }
889  $this->last_questionblock_id = $qdata["questionblock_id"];
890  }
891  $anchor_id = "svyrdq" . $qdata["question_id"];
892  $list->addListNode("<a href='#" . $anchor_id . "'>" . $qdata["title"] . "</a>", $qdata["question_id"], $qdata["questionblock_id"] ?
893  "q" . $qdata["questionblock_id"] : 0);
894  }
895  }
896 
897  if ($details) {
898  $list->setListClass("il_Explorer");
899  $toc_tpl->setVariable("LIST", $list->getHTML());
900 
901  //TABLE OF CONTENTS
902  $panel_toc = $ui_factory->panel()->standard("", $ui_factory->legacy($toc_tpl->get()));
903  $render_toc = $ui_renderer->render($panel_toc);
904  $dtmpl->setVariable("PANEL_TOC", $render_toc);
905 
906  //REPORT
907  $report_title = "";
908  $panel_report = $ui_factory->panel()->report($report_title, $this->array_panels);
909  $render_report = $ui_renderer->render($panel_report);
910  $dtmpl->setVariable("PANEL_REPORT", $render_report);
911 
912  //print the main template
913  $this->tpl->setVariable('DETAIL', $dtmpl->get());
914  }
915  }
916 
917  $this->tpl->setVariable('MODAL', $modal);
918  if (!$details) {
919  $table_gui = new ilSurveyResultsCumulatedTableGUI($this, $details ? 'evaluationdetails' : 'evaluation', $results);
920  $this->tpl->setVariable('CUMULATED', $table_gui->getHTML());
921  }
922  unset($dtmpl);
923  unset($table_gui);
924  unset($modal);
925 
926 
927  // print header
928 
929  $path = "";
930  $path_full = $tree->getPathFull($this->object->getRefId());
931  foreach ($path_full as $data) {
932  $path .= " &raquo; ";
933  $path .= $data['title'];
934  }
935 
937 
938  $props = array(
939  $this->lng->txt("link") => ilLink::_getStaticLink($this->object->getRefId()),
940  $this->lng->txt("path") => $path,
941  $this->lng->txt("svy_results") => !$details
942  ? $this->lng->txt("svy_eval_cumulated")
943  : $this->lng->txt("svy_eval_detail"),
944  $this->lng->txt("date") => ilDatePresentation::formatDate(new ilDateTime(time(), IL_CAL_UNIX)),
945  );
946 
947  $this->tpl->setCurrentBlock("print_header_bl");
948  foreach ($props as $key => $value) {
949  $this->tpl->setVariable("HEADER_PROP_KEY", $key);
950  $this->tpl->setVariable("HEADER_PROP_VALUE", $value);
951  $this->tpl->parseCurrentBlock();
952  }
953 
954  $this->log->debug("end");
955  if ($pdf) {
956  $html = $this->tpl->printToString();
957  if ($return_pdf) {
958  return $html;
959  } else {
960  $this->generateAndSendPDF($html);
961  }
962  }
963 
964  // $this->tpl->addCss("./Modules/Survey/templates/default/survey_print.css", "print");
965  }
966 
977  //protected function renderDetails($a_details_parts, $a_details_figure, ilTemplate $a_tpl, array $a_qdata, SurveyQuestionEvaluation $a_eval, $a_results)
978  protected function renderDetails($a_details_parts, $a_details_figure, array $a_qdata, SurveyQuestionEvaluation $a_eval, $a_results, $pdf)
979  {
980  $ui_factory = $this->ui->factory();
981  $a_tpl = new ilTemplate("tpl.svy_results_details_panel.html", true, true, "Modules/Survey");
982 
983  $question_res = $a_results;
984  $matrix = false;
985  if (is_array($question_res)) {
986  $question_res = $question_res[0][1];
987  $matrix = true;
988  }
989 
990  // see #28507 (matrix question without a row)
991  if (!is_object($question_res)) {
992  return;
993  }
994 
995  $question = $question_res->getQuestion();
996 
997  // question "overview"
998 
999  // :TODO: present subtypes (hrz/vrt, mc/sc mtx)?
1000 
1001  $a_tpl->setVariable("QTYPE", SurveyQuestion::_getQuestionTypeName($question->getQuestionType()));
1002 
1003  $kv = array();
1004  $kv["users_answered"] = $question_res->getUsersAnswered();
1005  $kv["users_skipped"] = $question_res->getUsersSkipped();
1006 
1007  if (!$matrix) {
1008  if ($question_res->getModeValue() !== null) {
1009  $kv["mode"] = wordwrap($question_res->getModeValueAsText(), 50, "<br />");
1010  $kv["mode_nr_of_selections"] = $question_res->getModeNrOfSelections();
1011  }
1012  if ($question_res->getMedian() !== null) {
1013  $kv["median"] = $question_res->getMedianAsText();
1014  }
1015  if ($question_res->getMean() !== null) {
1016  $kv["arithmetic_mean"] = $question_res->getMean();
1017  }
1018  }
1019 
1020  $svy_type_title = SurveyQuestion::_getQuestionTypeName($question->getQuestionType());
1021  $qst_title = $question->getTitle();
1022  $svy_text = nl2br($question->getQuestiontext());
1023  $card_table_tpl = new ilTemplate("tpl.svy_results_details_card.html", true, true, "Modules/Survey");
1024  foreach ($kv as $key => $value) {
1025  $card_table_tpl->setCurrentBlock("question_statistics_card");
1026  $card_table_tpl->setVariable("QUESTION_STATISTIC_KEY", $this->lng->txt($key));
1027  $card_table_tpl->setVariable("QUESTION_STATISTIC_VALUE", $value);
1028  $card_table_tpl->parseCurrentBlock();
1029  }
1030 
1031  // patch BGHW: added anchor
1032  $anchor_id = "svyrdq" . $question->getId();
1033  $title = "<span id='$anchor_id'>$qst_title</span>";
1034  $panel_qst_card = $ui_factory->panel()->sub($title, $ui_factory->legacy($svy_text))
1035  ->withCard($ui_factory->card()->standard($svy_type_title)->withSections(array($ui_factory->legacy($card_table_tpl->get()))));
1036 
1037  //commit 715c28815 from phantom patch
1038  //$anchor = "<a name='".$anchor_id."'></a>";
1039  //$panel_qst_card = $ui_factory->panel()->sub($anchor.$qst_title, $ui_factory->legacy($svy_text))
1040  //->withCard($ui_factory->card($svy_type_title)->withSections(array($ui_factory->legacy($card_table_tpl->get()))));
1041 
1042  array_push($this->array_panels, $panel_qst_card);
1043 
1044  // grid
1045  if ($a_details_parts == "t" ||
1046  $a_details_parts == "tc") {
1047  $grid = $a_eval->getGrid(
1048  $a_results,
1049  ($a_details_figure == "ap" || $a_details_figure == "a"),
1050  ($a_details_figure == "ap" || $a_details_figure == "p")
1051  );
1052  if ($grid) {
1053  foreach ($grid["cols"] as $col) {
1054  $a_tpl->setCurrentBlock("grid_col_header_bl");
1055  $a_tpl->setVariable("COL_HEADER", $col);
1056  $a_tpl->parseCurrentBlock();
1057  }
1058  foreach ($grid["rows"] as $cols) {
1059  foreach ($cols as $idx => $col) {
1060  if ($idx > 0) {
1061  $a_tpl->touchBlock("grid_col_nowrap_bl");
1062  }
1063 
1064  $a_tpl->setCurrentBlock("grid_col_bl");
1065  $a_tpl->setVariable("COL_CAPTION", trim($col));
1066  $a_tpl->parseCurrentBlock();
1067  }
1068 
1069  $a_tpl->touchBlock("grid_row_bl");
1070  }
1071  }
1072  }
1073 
1074  // text answers
1075  $texts = $a_eval->getTextAnswers($a_results);
1076  if ($texts) {
1077  if (array_key_exists("", $texts)) {
1078  $a_tpl->setVariable("TEXT_HEADING", $this->lng->txt("given_answers"));
1079  foreach ($texts[""] as $item) {
1080  $a_tpl->setCurrentBlock("text_direct_item_bl");
1081  $a_tpl->setVariable("TEXT_DIRECT", nl2br(htmlentities($item)));
1082  $a_tpl->parseCurrentBlock();
1083  }
1084  } else {
1085  $acc = new ilAccordionGUI();
1086  // patch BGHW: fixed accordion in pdf output
1087  if ($_GET["pdf"] == 1) {
1088  $acc->setBehaviour(ilAccordionGUI::FORCE_ALL_OPEN);
1089  }
1090  $acc->setId("svyevaltxt" . $question->getId());
1091 
1092  $a_tpl->setVariable("TEXT_HEADING", $this->lng->txt("freetext_answers"));
1093 
1094  foreach ($texts as $var => $items) {
1095  $list = array("<ul class=\"small\">");
1096  foreach ($items as $item) {
1097  $list[] = "<li>" . nl2br(htmlentities($item)) . "</li>";
1098  }
1099  $list[] = "</ul>";
1100  $acc->addItem($var, implode("\n", $list));
1101  }
1102 
1103  $a_tpl->setVariable("TEXT_ACC", $acc->getHTML());
1104  }
1105  }
1106 
1107  // chart
1108  if ($a_details_parts == "c" ||
1109  $a_details_parts == "tc") {
1110  $chart = $a_eval->getChart($a_results);
1111  if ($chart) {
1112  if (is_array($chart)) {
1113  // legend
1114  if (is_array($chart[1])) {
1115  foreach ($chart[1] as $legend_item) {
1116  $r = hexdec(substr($legend_item[1], 1, 2));
1117  $g = hexdec(substr($legend_item[1], 3, 2));
1118  $b = hexdec(substr($legend_item[1], 5, 2));
1119 
1120  $a_tpl->setCurrentBlock("legend_bl");
1121  $a_tpl->setVariable("LEGEND_CAPTION", $legend_item[0]);
1122  $a_tpl->setVariable("LEGEND_COLOR", $legend_item[1]);
1123  $a_tpl->setVariable("LEGEND_COLOR_SVG", $r . "," . $g . "," . $b);
1124  $a_tpl->parseCurrentBlock();
1125  }
1126  }
1127 
1128  $chart = $chart[0];
1129  }
1130 
1131  // patch BGHW jluezen
1132  if (!$pdf) {
1133  $this->ctrl->setParameter($this, "qid", $question->getId());
1134  $url = $this->ctrl->getLinkTarget($this, "downloadChart");
1135  $this->ctrl->setParameter($this, "qid", "");
1136  }
1137 
1138  $a_tpl->setVariable("CHART", $chart);
1139  $a_tpl->setVariable("CHART_DL_URL", $url);
1140  $a_tpl->setVariable("CHART_DL_TXT", $this->lng->txt("svy_chart_download"));
1141  }
1142  }
1143 
1144  $panel = $ui_factory->panel()->sub("", $ui_factory->legacy($a_tpl->get()));
1145  array_push($this->array_panels, $panel);
1146  }
1147 
1154  public function addApprSelectionToToolbar()
1155  {
1156  $ilToolbar = $this->toolbar;
1158 
1159  $svy_mode = $this->object->getMode();
1160  if ($svy_mode == ilObjSurvey::MODE_360 || $svy_mode == ilObjSurvey::MODE_SELF_EVAL) {
1161  $appr_id = $this->getAppraiseeId();
1162 
1163  $options = array();
1164  if (!$appr_id) {
1165  $options[""] = $this->lng->txt("please_select");
1166  }
1167 
1168  $no_appr = true;
1169  if ($this->object->get360Mode()) {
1170  foreach ($this->object->getAppraiseesData() as $item) {
1171  if ($item["closed"]) {
1172  $options[$item["user_id"]] = $item["login"];
1173  $no_appr = false;
1174  }
1175  }
1176  } else { //self evaluation mode
1177  foreach ($this->object->getSurveyParticipants() as $item) {
1178  $options[ilObjUser::_lookupId($item['login'])] = $item['login'];
1179  $no_appr = false;
1180  }
1181  }
1182 
1183  if (!$no_appr) {
1184  if ($rbacsystem->checkAccess("write", $this->object->getRefId()) ||
1185  $this->object->get360Results() == ilObjSurvey::RESULTS_360_ALL ||
1186  $this->object->getSelfEvaluationResults() == ilObjSurvey::RESULTS_SELF_EVAL_ALL) {
1187  $appr = new ilSelectInputGUI($this->lng->txt("svy_participant"), "appr_id");
1188  $appr->setOptions($options);
1189  $appr->setValue($this->getAppraiseeId());
1190  $ilToolbar->addInputItem($appr, true);
1191 
1192  $button = ilSubmitButton::getInstance();
1193  $button->setCaption("survey_360_select_appraisee");
1194  $button->setCommand($this->ctrl->getCmd());
1195  $ilToolbar->addButtonInstance($button);
1196 
1197  if ($appr_id) {
1198  $ilToolbar->addSeparator();
1199  }
1200  }
1201  } else {
1202  ilUtil::sendFailure($this->lng->txt("survey_360_no_closed_appraisees"));
1203  }
1204  }
1205  }
1206 
1217  public function processCSVRow($row, $quoteAll = false, $separator = ";")
1218  {
1219  $resultarray = array();
1220  foreach ($row as $rowindex => $entry) {
1221  if (is_array($entry)) {
1222  $entry = implode("/", $entry);
1223  }
1224  $surround = false;
1225  if ($quoteAll) {
1226  $surround = true;
1227  }
1228  if (strpos($entry, "\"") !== false) {
1229  $entry = str_replace("\"", "\"\"", $entry);
1230  $surround = true;
1231  }
1232  if (strpos($entry, $separator) !== false) {
1233  $surround = true;
1234  }
1235  // replace all CR LF with LF (for Excel for Windows compatibility
1236  $entry = str_replace(chr(13) . chr(10), chr(10), $entry);
1237  if ($surround) {
1238  $resultarray[$rowindex] = utf8_decode("\"" . $entry . "\"");
1239  } else {
1240  $resultarray[$rowindex] = utf8_decode($entry);
1241  }
1242  }
1243  return $resultarray;
1244  }
1245 
1246 
1247  public function exportEvaluationUser()
1248  {
1249  // build title row(s)
1250 
1251  $title_row = $title_row2 = array();
1252  $title_row[] = $this->lng->txt("lastname"); // #12756
1253  $title_row[] = $this->lng->txt("firstname");
1254  $title_row[] = $this->lng->txt("login");
1255  $title_row[] = $this->lng->txt('workingtime'); // #13622
1256  $title_row[] = $this->lng->txt('survey_results_finished');
1257  $title_row2[] = "";
1258  $title_row2[] = "";
1259  $title_row2[] = "";
1260  $title_row2[] = "";
1261  $title_row2[] = "";
1262  if ($this->object->canExportSurveyCode()) {
1263  $title_row[] = $this->lng->txt("codes");
1264  $title_row2[] = "";
1265  }
1266 
1267  $questions = array();
1268 
1269  foreach ($this->object->getSurveyQuestions() as $qdata) {
1270  $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($qdata["question_id"], $finished_ids);
1271  $q_res = $q_eval->getResults();
1272 
1273  $questions[$qdata["question_id"]] = array($q_eval, $q_res);
1274 
1275  $question = is_array($q_res)
1276  ? $q_res[0][1]->getQuestion()
1277  : $q_res->getQuestion();
1278 
1279  $do_title = $do_label = true;
1280  switch ($_POST['export_label']) {
1281  case "label_only":
1282  $title_row[] = $question->label;
1283  $title_row2[] = "";
1284  $do_title = false;
1285  break;
1286 
1287  case "title_only":
1288  $title_row[] = $question->getTitle();
1289  $title_row2[] = "";
1290  $do_label = false;
1291  break;
1292 
1293  default:
1294  $title_row[] = $question->getTitle();
1295  $title_row2[] = $question->label;
1296  break;
1297  }
1298 
1299  $q_eval->getUserSpecificVariableTitles($title_row, $title_row2, $do_title, $do_label);
1300  }
1301 
1302  $rows = array();
1303 
1304  // add title row(s)
1305  $rows[] = $title_row;
1306  if (implode("", $title_row2)) {
1307  $rows[] = $title_row2;
1308  }
1309 
1310  // #13620
1312 
1313  $finished_ids = null;
1314  if ($this->object->get360Mode()) {
1315  $appr_id = $_REQUEST["appr_id"];
1316  if (!$appr_id) {
1317  $this->ctrl->redirect($this, "evaluationuser");
1318  }
1319  $finished_ids = $this->object->getFinishedIdsForAppraiseeId($appr_id);
1320  if (!sizeof($finished_ids)) {
1321  $finished_ids = array(-1);
1322  }
1323  }
1324 
1325  //$participants = $this->object->getSurveyParticipants($finished_ids);
1326  $participants = $this->filterSurveyParticipantsByAccess($finished_ids);
1327 
1328  foreach ($participants as $user) {
1329  $user_id = $user["active_id"];
1330 
1331  $row = array();
1332  $row[] = trim($user["lastname"])
1333  ? $user["lastname"]
1334  : $user["name"]; // anonymous
1335  $row[] = $user["firstname"];
1336  $row[] = $user["login"]; // #10579
1337 
1338  if ($this->object->canExportSurveyCode()) {
1339  $row[] = $user_id;
1340  }
1341 
1342  $row[] = $this->object->getWorkingtimeForParticipant($user_id);
1343 
1344  if ((bool) $user["finished"]) {
1345  $dt = new ilDateTime($user["finished_tstamp"], IL_CAL_UNIX);
1346  $row[] = ($_POST["export_format"] == self::TYPE_XLS)
1347  ? $dt
1349  } else {
1350  $row[] = "-"; // :TODO:
1351  }
1352 
1353  foreach ($questions as $item) {
1354  $q_eval = $item[0];
1355  $q_res = $item[1];
1356 
1357  $q_eval->addUserSpecificResults($row, $user_id, $q_res);
1358  }
1359 
1360  $rows[] = $row;
1361  }
1362 
1363  // #11179
1364  $surveyname = $this->object->getTitle() . " " . $this->lng->txt("svy_eval_user") . " " . date("Y-m-d");
1365  $surveyname = preg_replace("/\s/", "_", trim($surveyname));
1366  $surveyname = ilUtil::getASCIIFilename($surveyname);
1367 
1368  switch ($_POST["export_format"]) {
1369  case self::TYPE_XLS:
1370  $excel = new ilExcel();
1371  $excel->addSheet($this->lng->txt("svy_eval_user"));
1372 
1373  foreach ($rows as $row_idx => $row) {
1374  foreach ($row as $col_idx => $col) {
1375  $excel->setCell($row_idx + 1, $col_idx, $col);
1376  }
1377  if (!$row_idx) {
1378  $excel->setBold("A1:" . $excel->getColumnCoord(sizeof($row) - 1) . "1");
1379  }
1380  }
1381  $excel->sendToClient($surveyname);
1382 
1383  // no break
1384  case self::TYPE_SPSS:
1385  $csv = "";
1386  $separator = ";";
1387  foreach ($rows as $csvrow) {
1388  $csvrow = str_replace("\n", " ", $this->processCSVRow($csvrow, true, $separator));
1389  $csv .= join($separator, $csvrow) . "\n";
1390  }
1391  ilUtil::deliverData($csv, "$surveyname.csv");
1392  exit();
1393  }
1394  }
1395 
1403  public function evaluationuser()
1404  {
1405  $ilAccess = $this->access;
1406  $ilToolbar = $this->toolbar;
1407 
1408  if (!$this->hasResultsAccess() &&
1409  $this->object->getMode() != ilObjSurvey::MODE_SELF_EVAL) {
1410  ilUtil::sendFailure($this->lng->txt("no_permission"), true);
1411  $this->ctrl->redirectByClass("ilObjSurveyGUI", "infoScreen");
1412  }
1413 
1414  $ilToolbar->setFormAction($this->ctrl->getFormAction($this, "evaluationuser"));
1415 
1416  if ($this->object->get360Mode()) {
1417  $appr_id = $this->getAppraiseeId();
1418  $this->addApprSelectionToToolbar();
1419  }
1420 
1421  $tabledata = null;
1422  if (!$this->object->get360Mode() || $appr_id) {
1423  $modal_id = "svy_ev_exp";
1424  $modal = $this->buildExportModal($modal_id, "exportevaluationuser");
1425 
1426  $button = ilLinkButton::getInstance();
1427  $button->setCaption("export");
1428  $button->setOnClick('$(\'#' . $modal_id . '\').modal(\'show\')');
1429  $ilToolbar->addButtonInstance($button);
1430 
1431  $ilToolbar->addSeparator();
1432 
1433  $button = ilLinkButton::getInstance();
1434  $button->setCaption("print");
1435  $button->setOnClick("window.print(); return false;");
1436  $button->setOmitPreventDoubleSubmission(true);
1437  $ilToolbar->addButtonInstance($button);
1438 
1439  $finished_ids = null;
1440  if ($appr_id) {
1441  $finished_ids = $this->object->getFinishedIdsForAppraiseeId($appr_id);
1442  if (!sizeof($finished_ids)) {
1443  $finished_ids = array(-1);
1444  }
1445  }
1446 
1447  $data = $this->parseUserSpecificResults($finished_ids);
1448  }
1449 
1450  $table_gui = new ilSurveyResultsUserTableGUI($this, 'evaluationuser', $this->object->hasAnonymizedResults());
1451  $table_gui->setData($data);
1452  $this->tpl->setContent($table_gui->getHTML() . $modal);
1453  }
1454 
1455  protected function filterSurveyParticipantsByAccess($a_finished_ids)
1456  {
1457  $all_participants = $this->object->getSurveyParticipants($a_finished_ids);
1458  $participant_ids = [];
1459  foreach ($all_participants as $participant) {
1460  $participant_ids[] = $participant['usr_id'];
1461  }
1462 
1463 
1464  $filtered_participant_ids = $this->access->filterUserIdsByRbacOrPositionOfCurrentUser(
1465  'read_results',
1466  'access_results',
1467  $this->object->getRefId(),
1468  $participant_ids
1469  );
1470  $participants = [];
1471  foreach ($all_participants as $username => $user_data) {
1472  if (!$user_data['usr_id']) {
1473  $participants[$username] = $user_data;
1474  }
1475  if (in_array($user_data['usr_id'], $filtered_participant_ids)) {
1476  $participants[$username] = $user_data;
1477  }
1478  }
1479  return $participants;
1480  }
1481 
1482 
1483 
1484  protected function parseUserSpecificResults(array $a_finished_ids = null)
1485  {
1486  $data = array();
1487 
1488  $participants = $this->filterSurveyParticipantsByAccess($a_finished_ids);
1489 
1490  foreach ($this->object->getSurveyQuestions() as $qdata) {
1491  $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($qdata["question_id"], $a_finished_ids);
1492  $q_res = $q_eval->getResults();
1493 
1494  // see #28507 (matrix question without a row)
1495  if (is_array($q_res) && !is_object($q_res[0][1])) {
1496  continue;
1497  }
1498 
1499  $question = is_array($q_res)
1500  ? $q_res[0][1]->getQuestion()
1501  : $q_res->getQuestion();
1502 
1503  foreach ($participants as $user) {
1504  $user_id = $user["active_id"];
1505 
1506  $parsed_results = $q_eval->parseUserSpecificResults($q_res, $user_id);
1507 
1508  if (!array_key_exists($user_id, $data)) {
1509  $wt = $this->object->getWorkingtimeForParticipant($user_id);
1510 
1511  $finished = $user["finished"]
1512  ? $user["finished_tstamp"]
1513  : false;
1514 
1515  $data[$user_id] = array(
1516  "username" => $user["sortname"],
1517  "question" => $question->getTitle(),
1518  "results" => $parsed_results,
1519  "workingtime" => $wt,
1520  "finished" => $finished,
1521  "subitems" => array()
1522  );
1523  } else {
1524  $data[$user_id]["subitems"][] = array(
1525  "username" => " ",
1526  "question" => $question->getTitle(),
1527  "results" => $parsed_results,
1528  "workingtime" => null,
1529  "finished" => null
1530  );
1531  }
1532  }
1533  }
1534 
1535  return $data;
1536  }
1537 
1544  public function competenceEval()
1545  {
1546  $ilUser = $this->user;
1547  $lng = $this->lng;
1548  $ilCtrl = $this->ctrl;
1549  $ilToolbar = $this->toolbar;
1550  $tpl = $this->tpl;
1551  $ilTabs = $this->tabs;
1552 
1553  $survey = $this->object;
1554 
1555  $ilTabs->activateSubtab("svy_eval_competences");
1556  $ilTabs->activateTab("svy_results");
1557 
1558  $ilToolbar->setFormAction($this->ctrl->getFormAction($this, "competenceEval"));
1559 
1560  if ($this->object->get360Mode() || $survey->getMode() == ilObjSurvey::MODE_SELF_EVAL) {
1561  $appr_id = $this->getAppraiseeId();
1562  $this->addApprSelectionToToolbar();
1563  }
1564 
1565  if ($appr_id == 0) {
1566  return;
1567  }
1568 
1569  // evaluation modes
1570  $eval_modes = array();
1571 
1572  // get all competences of survey
1573  $sskill = new ilSurveySkill($survey);
1574  $opts = $sskill->getAllAssignedSkillsAsOptions();
1575  $skills = array();
1576  foreach ($opts as $id => $o) {
1577  $idarr = explode(":", $id);
1578  $skills[$id] = array("id" => $id, "title" => $o, "profiles" => array(),
1579  "base_skill" => $idarr[0], "tref_id" => $idarr[1]);
1580  }
1581 
1582  // get matching user competence profiles
1583  // -> add gap analysis to profile
1585  foreach ($profiles as $p) {
1586  $prof = new ilSkillProfile($p["id"]);
1587  $prof_levels = $prof->getSkillLevels();
1588  foreach ($prof_levels as $pl) {
1589  if (isset($skills[$pl["base_skill_id"] . ":" . $pl["tref_id"]])) {
1590  $skills[$pl["base_skill_id"] . ":" . $pl["tref_id"]]["profiles"][] =
1591  $p["id"];
1592 
1593  $eval_modes["gap_" . $p["id"]] =
1594  $lng->txt("svy_gap_analysis") . ": " . $prof->getTitle();
1595  }
1596  }
1597  }
1598  //var_dump($skills);
1599  //var_dump($eval_modes);
1600 
1601  // if one competence does not match any profiles
1602  // -> add "competences of survey" alternative
1603  reset($skills);
1604  foreach ($skills as $sk) {
1605  if (count($sk["profiles"]) == 0) {
1606  $eval_modes["skills_of_survey"] = $lng->txt("svy_all_survey_competences");
1607  }
1608  }
1609 
1610  // final determination of current evaluation mode
1611  $comp_eval_mode = $_GET["comp_eval_mode"];
1612  if ($_POST["comp_eval_mode"] != "") {
1613  $comp_eval_mode = $_POST["comp_eval_mode"];
1614  }
1615 
1616  if (!isset($eval_modes[$comp_eval_mode])) {
1617  reset($eval_modes);
1618  $comp_eval_mode = key($eval_modes);
1619  $ilCtrl->setParameter($this, "comp_eval_mode", $comp_eval_mode);
1620  }
1621 
1622  $ilCtrl->saveParameter($this, "comp_eval_mode");
1623 
1624  $mode_sel = new ilSelectInputGUI($lng->txt("svy_analysis"), "comp_eval_mode");
1625  $mode_sel->setOptions($eval_modes);
1626  $mode_sel->setValue($comp_eval_mode);
1627  $ilToolbar->addInputItem($mode_sel, true);
1628 
1629  $ilToolbar->addFormButton($lng->txt("select"), "competenceEval");
1630 
1631  if (substr($comp_eval_mode, 0, 4) == "gap_") {
1632  // gap analysis
1633  $profile_id = (int) substr($comp_eval_mode, 4);
1634 
1635  $pskills_gui = new ilPersonalSkillsGUI();
1636  $pskills_gui->setProfileId($profile_id);
1637  $pskills_gui->setGapAnalysisActualStatusModePerObject($survey->getId(), $lng->txt("skmg_eval_type_1"));
1638  if ($survey->getFinishedIdForAppraiseeIdAndRaterId($appr_id, $appr_id) > 0) {
1639  $sskill = new ilSurveySkill($survey);
1640  $self_levels = array();
1641  foreach ($sskill->determineSkillLevelsForAppraisee($appr_id, true) as $sl) {
1642  $self_levels[$sl["base_skill_id"]][$sl["tref_id"]] = $sl["new_level_id"];
1643  }
1644  $pskills_gui->setGapAnalysisSelfEvalLevels($self_levels);
1645  }
1646  $html = $pskills_gui->getGapAnalysisHTML($appr_id);
1647 
1648  $tpl->setContent($html);
1649  } else { // must be all survey competences
1650  $pskills_gui = new ilPersonalSkillsGUI();
1651  #23743
1652  if ($survey->getMode() != ilObjSurvey::MODE_SELF_EVAL) {
1653  $pskills_gui->setGapAnalysisActualStatusModePerObject($survey->getId(), $lng->txt("skmg_eval_type_1"));
1654  }
1655  if ($survey->getFinishedIdForAppraiseeIdAndRaterId($appr_id, $appr_id) > 0) {
1656  $sskill = new ilSurveySkill($survey);
1657  $self_levels = array();
1658  foreach ($sskill->determineSkillLevelsForAppraisee($appr_id, true) as $sl) {
1659  $self_levels[$sl["base_skill_id"]][$sl["tref_id"]] = $sl["new_level_id"];
1660  }
1661  $pskills_gui->setGapAnalysisSelfEvalLevels($self_levels);
1662  }
1663  $sk = array();
1664  foreach ($skills as $skill) {
1665  $sk[] = array(
1666  "base_skill_id" => (int) $skill["base_skill"],
1667  "tref_id" => (int) $skill["tref_id"]
1668  );
1669  }
1670  $html = $pskills_gui->getGapAnalysisHTML($appr_id, $sk);
1671 
1672  $tpl->setContent($html);
1673  }
1674  }
1675 
1679  protected function hasResultsAccess()
1680  {
1681  return $this->access->checkRbacOrPositionPermissionAccess('read_results', 'access_results', $this->object->getRefId());
1682  }
1683 
1684  public function evaluationpdf()
1685  {
1686  $this->evaluation(0, true);
1687  }
1688 
1689  public function evaluationdetailspdf()
1690  {
1691  $this->evaluation(1, true);
1692  }
1693 
1694  public function downloadChart()
1695  {
1696  $qid = (int) $_GET["qid"];
1697  if (!$qid) {
1698  return;
1699  }
1700 
1701  $this->renderChartOnly();
1702  }
1703 
1704  public function renderChartOnly()
1705  {
1706  global $tpl;
1707 
1708  $qid = (int) $_GET["qid"];
1709  if (!$qid) {
1710  return;
1711  }
1712 
1713  $finished_ids = null;
1714  if ($this->object->get360Mode()) {
1715  $appr_id = $this->getAppraiseeId();
1716  $finished_ids = $this->object->getFinishedIdsForAppraiseeId($appr_id);
1717  if (!sizeof($finished_ids)) {
1718  $finished_ids = array(-1);
1719  }
1720  }
1721 
1722  // parse answer data in evaluation results
1723  foreach ($this->object->getSurveyQuestions() as $qdata) {
1724  if ($qid == $qdata["question_id"]) {
1725  $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($qdata["question_id"], $finished_ids);
1726  $q_res = $q_eval->getResults();
1727 
1728  $chart = $q_eval->getChart($q_res);
1729  if ($chart) {
1730  $dtmpl = new ilTemplate("tpl.il_svy_svy_results_details_single.html", true, true, "Modules/Survey");
1731 
1732  if (is_array($chart)) {
1733  // legend
1734  if (is_array($chart[1])) {
1735  foreach ($chart[1] as $legend_item) {
1736  $dtmpl->setCurrentBlock("legend_bl");
1737  $dtmpl->setVariable("LEGEND_CAPTION", $legend_item[0]);
1738  $dtmpl->setVariable("LEGEND_COLOR", $legend_item[1]);
1739  $dtmpl->parseCurrentBlock();
1740  }
1741  }
1742 
1743  $chart = $chart[0];
1744  }
1745  $dtmpl->setVariable("CHART", $chart);
1746  }
1747  }
1748  }
1749 
1750  // "print view"
1751  $this->tpl->setContent($dtmpl->get());
1752 
1753  $html = $this->tpl->printToString();
1754  $this->generateAndSendPDF($html, $this->object->getTitle() . " - " . SurveyQuestion::_getTitle($qid) . ".pdf");
1755  }
1756 
1763  public function generateAndSendPDF($html, $filename = "")
1764  {
1765  // :TODO: fixing css dummy parameters
1766  $html = preg_replace("/\?dummy\=[0-9]+/", "", $html);
1767  $html = preg_replace("/\?vers\=[0-9A-Za-z\-]+/", "", $html);
1768  $html = str_replace('.css$Id$', ".css", $html);
1769  $html = preg_replace("/src=\"\\.\\//ims", "src=\"" . ILIAS_HTTP_PATH . "/", $html);
1770  $html = preg_replace("/href=\"\\.\\//ims", "href=\"" . ILIAS_HTTP_PATH . "/", $html);
1771 
1772  //echo $html; exit;
1773 
1774  if ($filename == "") {
1775  $filename = $this->object->getTitle() . ".pdf";
1776  }
1777  $pdf_factory = new ilHtmlToPdfTransformerFactory();
1778  $pdf_factory->deliverPDFFromHTMLString($html, $filename, ilHtmlToPdfTransformerFactory::PDF_OUTPUT_DOWNLOAD, "Survey", "Results");
1779  }
1780 
1781  public function callPdfGeneration($a_url, $a_suffix, $a_filename, $a_return = false)
1782  {
1783  $script = ILIAS_ABSOLUTE_PATH . "/Modules/Survey/js/phantom.js";
1784 
1785  $bin = ilUtil::isWindows()
1786  ? ILIAS_ABSOLUTE_PATH . "/libs/composer/vendor/jakoch/phantomjs/bin/phantomjs.exe"
1787  : ILIAS_ABSOLUTE_PATH . "/libs/composer/vendor/jakoch/phantomjs/bin/phantomjs";
1788 
1789  $parts = parse_url(ILIAS_HTTP_PATH);
1790 
1791  $target = ilUtil::ilTempnam() . "." . $a_suffix;
1792  $path = $parts["path"];
1793  if (empty($path)) {
1794  $path = "''";
1795  }
1796 
1797  $args = array(
1798  session_id(),
1799  $parts["host"],
1800  $parts["path"] ? $parts["path"] : '/',
1801  CLIENT_ID,
1802  "\"" . ILIAS_HTTP_PATH . "/" . $a_url . "\"",
1803  $target
1804  );
1805 
1806  ilSession::_writeData(session_id(), session_encode());
1807 
1808  $output = $return = "";
1809 
1810  exec($executable_string = $bin . " " . $script . " " . implode(" ", $args), $output, $return);
1811 
1813  $log->debug($executable_string);
1814  $log->dump($output, ilLogLevel::DEBUG);
1815  $log->dump($return, ilLogLevel::DEBUG);
1816 
1817  $mime_type = '';
1818  if (substr($a_filename, -3) == 'pdf') {
1819  $mime_type = 'application/pdf';
1820  } elseif (substr($a_filename, -3) == 'png') {
1821  $mime_type = 'image/png';
1822  }
1823 
1824  if (!$a_return) {
1825  ilUtil::deliverFile($target, $a_filename, $mime_type);
1826  } else {
1827  ilLoggerFactory::getRootLogger()->debug("**** Return a target = " . $target);
1828  return $target;
1829  }
1830  }
1831 }
static deliverData($a_data, $a_filename, $mime="application/octet-stream", $charset="")
deliver data for download via browser.
getExportGrid($a_results)
Get grid data.
parseResultsToExcel(ilExcel $a_excel, ilSurveyEvaluationResults $a_results, &$a_excel_row, array $a_grid=null, array $a_text_answers=null, $a_include_mode=true)
exit
Definition: login.php:29
exportResultsDetailsExcel(ilExcel $a_excel, SurveyQuestionEvaluation $a_eval, $a_results, $a_do_title, $a_do_label)
Export details (excel only)
$data
Definition: storeScorm.php:23
setEvalSubtabs()
Set the tabs for the evaluation output.
evaluationuser()
Print the survey evaluation for a selected user.
$_SESSION["AccountId"]
const EVALUATION_ACCESS_OFF
This class represents a property form user interface.
$type
const EVALUATION_ACCESS_PARTICIPANTS
$_GET["client_id"]
cancelEvaluationAccess()
Cancels the input of the survey access code for evaluation access.
renderDetails($a_details_parts, $a_details_figure, array $a_qdata, SurveyQuestionEvaluation $a_eval, $a_results, $pdf)
Render details.
static _getTitle($question_id)
Returns the question title of a question with a given id.
$valid
Nested List.
setAppraiseeId($a_val)
Set appraisee id.
evaluation($details=0, $pdf=false, $return_pdf=false)
static _lookupId($a_user_str)
Lookup id by login.
static setUseRelativeDates($a_status)
set use relative dates
addApprSelectionToToolbar()
Add appraisee selection to toolbar.
parseUserSpecificResults(array $a_finished_ids=null)
static _getQuestionTypeName($type_tag)
Return the translation for a given question type tag.
const IL_CAL_UNIX
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false, $include_seconds=false)
Format a date public.
checkEvaluationAccess()
Checks the evaluation access after entering the survey access code.
user()
Definition: user.php:4
static isWindows()
check wether the current client system is a windows system
global $ilCtrl
Definition: ilias.php:18
Skill/Competence handling in surveys.
processCSVRow($row, $quoteAll=false, $separator=";")
Processes an array as a CSV row and converts the array values to correct CSV values.
getGrid($a_results, $a_abs=true, $a_perc=true)
Get grid data.
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
hasResultsAccess()
Check if user can view results granted by rbac or positions.
Personal skills GUI class.
static getProfilesOfUser($a_user_id)
Get profiles of a user.
addSheet($a_name, $a_activate=true)
Add sheet.
setBold($a_coords)
Set cell(s) to bold.
static _instanciateQuestionEvaluation($question_id, array $a_finished_ids=null)
Creates an instance of a question evaluation with a given question id.
Class ilHtmlToPdfTransformerFactory.
$log
Definition: result.php:15
static _lookupObjId($a_id)
competenceEval()
Competence Evaluation.
generateAndSendPDF($html, $filename="")
$format
Definition: metadata.php:218
$ilUser
Definition: imgupload.php:18
ui()
Definition: ui.php:5
getCoordByColumnAndRow($pColumn=1, $pRow=1)
Get cell coordinate (e.g.
checkAnonymizedEvaluationAccess()
Show the detailed evaluation.
setCell($a_row, $a_col, $a_value, $a_datatype=null)
Set cell value.
$results
static _getQuestionblock($questionblock_id)
Returns the database row for a given question block.
filterSurveyParticipantsByAccess($a_finished_ids)
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
$filename
Definition: buildRTE.php:89
$rows
Definition: xhr_table.php:10
const EVALUATION_ACCESS_ALL
static _hasEvaluationAccess($a_obj_id, $user_id)
static _writeData($a_session_id, $a_data)
Write session data.
static ilTempnam($a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
static getInstance()
Get instance.
callPdfGeneration($a_url, $a_suffix, $a_filename, $a_return=false)
setColors($a_coords, $a_background, $a_font=null)
Set cell(s) colors.
$ret
Definition: parser.php:6
__construct($a_object)
ilSurveyEvaluationGUI constructor
$DIC
Definition: xapitoken.php:46
static getLogger($a_component_id)
Get component logger.
$url
Survey evaluation graphical output.
evaluationdetails()
Show the detailed evaluation.
Accordion user interface class.
$cols
Definition: xhr_table.php:11
const RESULTS_SELF_EVAL_ALL
$_POST["username"]
const TYPE_SPSS
determineAppraiseeId()
Determine appraisee id.
static deliverFile( $a_file, $a_filename, $a_mime='', $isInline=false, $removeAfterDelivery=false, $a_exit_after=true)
deliver file for download via browser.
static getRootLogger()
The unique root logger has a fixed error level.
getTextAnswers($a_results)
Get text answers.