ILIAS  release_7 Revision v7.30-3-g800a261c036
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  if ($this->object->getCalculateSumScore()) {
165  $ilTabs->addSubTabTarget(
166  "svy_sum_score",
167  $this->ctrl->getLinkTarget($this, "sumscore"),
168  array("sumscore")
169  );
170  }
171  }
172 
173 
179  public function setAppraiseeId($a_val)
180  {
181  $this->appr_id = $a_val;
182  }
183 
189  public function getAppraiseeId()
190  {
191  return $this->appr_id;
192  }
193 
197  public function determineAppraiseeId()
198  {
201 
202  $appr_id = "";
203 
204  // always start with current user
205  if ($_REQUEST["appr_id"] == "") {
206  $req_appr_id = $ilUser->getId();
207  } else {
208  $req_appr_id = (int) $_REQUEST["appr_id"];
209  }
210 
211  // write access? allow selection
212  if ($req_appr_id > 0 && $this->object->get360Mode()) {
213  $all_appr = ($this->object->get360Results() == ilObjSurvey::RESULTS_360_ALL);
214 
215  $valid = array();
216  foreach ($this->object->getAppraiseesData() as $item) {
217  if ($item["closed"] &&
218  ($item["user_id"] == $ilUser->getId() ||
219  $rbacsystem->checkAccess("write", $this->object->getRefId()) ||
220  $all_appr)) {
221  $valid[] = $item["user_id"];
222  }
223  }
224  if (in_array($req_appr_id, $valid)) {
225  $appr_id = $req_appr_id;
226  } else {
227  // current selection / user is not valid, use 1st valid instead
228  $appr_id = array_shift($valid);
229  }
230  } else { // SVY SELF EVALUATION MODE
231  $appr_id = $req_appr_id;
232  }
233 
234  $this->ctrl->setParameter($this, "appr_id", $appr_id);
235  $this->setAppraiseeId($appr_id);
236  }
237 
238 
247  {
249 
250  if ($this->object->getAnonymize() == 1 &&
251  $_SESSION["anon_evaluation_access"] == $_GET["ref_id"]) {
252  return true;
253  }
254 
256  if ($this->object->getAnonymize() == 1) {
257  $_SESSION["anon_evaluation_access"] = $_GET["ref_id"];
258  }
259  return true;
260  }
261 
262  if ($this->object->getAnonymize() == 1) {
263  // autocode
264  $surveycode = $this->object->getUserAccessCode($ilUser->getId());
265  if ($this->object->isAnonymizedParticipant($surveycode)) {
266  $_SESSION["anon_evaluation_access"] = $_GET["ref_id"];
267  return true;
268  }
269 
270  /* try to find code for current (registered) user from existing run
271  if($this->object->findCodeForUser($ilUser->getId()))
272  {
273  $_SESSION["anon_evaluation_access"] = $_GET["ref_id"];
274  return true;
275  }
276  */
277 
278  // code needed
279  $this->tpl->setVariable("TABS", "");
280  $this->tpl->addBlockFile("ADM_CONTENT", "adm_content", "tpl.il_svy_svy_evaluation_checkaccess.html", "Modules/Survey");
281  $this->tpl->setCurrentBlock("adm_content");
282  $this->tpl->setVariable("AUTHENTICATION_NEEDED", $this->lng->txt("svy_check_evaluation_authentication_needed"));
283  $this->tpl->setVariable("FORM_ACTION", $this->ctrl->getFormAction($this, "checkEvaluationAccess"));
284  $this->tpl->setVariable("EVALUATION_CHECKACCESS_INTRODUCTION", $this->lng->txt("svy_check_evaluation_access_introduction"));
285  $this->tpl->setVariable("VALUE_CHECK", $this->lng->txt("ok"));
286  $this->tpl->setVariable("VALUE_CANCEL", $this->lng->txt("cancel"));
287  $this->tpl->setVariable("TEXT_SURVEY_CODE", $this->lng->txt("survey_code"));
288  $this->tpl->parseCurrentBlock();
289  }
290 
291  $_SESSION["anon_evaluation_access"] = null;
292  return false;
293  }
294 
302  public function checkEvaluationAccess()
303  {
304  $surveycode = $_POST["surveycode"];
305  if ($this->object->isAnonymizedParticipant($surveycode)) {
306  $_SESSION["anon_evaluation_access"] = $_GET["ref_id"];
307  $this->evaluation();
308  } else {
309  ilUtil::sendFailure($this->lng->txt("svy_check_evaluation_wrong_key", true));
310  $this->cancelEvaluationAccess();
311  }
312  }
313 
321  public function cancelEvaluationAccess()
322  {
323  $ilCtrl = $this->ctrl;
324  $tree = $this->tree;
325  $path = $tree->getPathFull($this->object->getRefID());
326  $ilCtrl->setParameterByClass(
327  "ilrepositorygui",
328  "ref_id",
329  $path[count($path) - 2]["child"]
330  );
331  $ilCtrl->redirectByClass("ilrepositorygui", "frameset");
332  }
333 
341  public function evaluationdetails()
342  {
343  $this->evaluation(1);
344  }
345 
346  public function exportCumulatedResults($details = 0)
347  {
348  $finished_ids = null;
349  if ($this->object->get360Mode()) {
350  $appr_id = $_REQUEST["appr_id"];
351  if (!$appr_id) {
352  $this->ctrl->redirect($this, $details ? "evaluationdetails" : "evaluation");
353  }
354  $finished_ids = $this->object->getFinishedIdsForAppraiseeId($appr_id);
355  if (!sizeof($finished_ids)) {
356  $finished_ids = array(-1);
357  }
358  }
359 
360  // titles
361  $title_row = array();
362  $do_title = $do_label = true;
363  switch ($_POST['export_label']) {
364  case 'label_only':
365  $title_row[] = $this->lng->txt("label");
366  $do_title = false;
367  break;
368 
369  case 'title_only':
370  $title_row[] = $this->lng->txt("title");
371  $do_label = false;
372  break;
373 
374  default:
375  $title_row[] = $this->lng->txt("title");
376  $title_row[] = $this->lng->txt("label");
377  break;
378  }
379  $title_row[] = $this->lng->txt("question");
380  $title_row[] = $this->lng->txt("question_type");
381  $title_row[] = $this->lng->txt("users_answered");
382  $title_row[] = $this->lng->txt("users_skipped");
383  $title_row[] = $this->lng->txt("mode");
384  $title_row[] = $this->lng->txt("mode_text");
385  $title_row[] = $this->lng->txt("mode_nr_of_selections");
386  $title_row[] = $this->lng->txt("median");
387  $title_row[] = $this->lng->txt("arithmetic_mean");
388 
389  // creating container
390  switch ($_POST["export_format"]) {
391  case self::TYPE_XLS:
392  $excel = new ilExcel();
393  $excel->addSheet($this->lng->txt("svy_eval_cumulated"));
394  $excel->setCellArray(array($title_row), "A1");
395  $excel->setBold("A1:" . $excel->getColumnCoord(sizeof($title_row) - 1) . "1");
396  break;
397 
398  case self::TYPE_SPSS:
399  $csvfile = array($title_row);
400  break;
401  }
402 
403 
404  // parse answer data in evaluation results
405  $ov_row = 2;
406  foreach ($this->object->getSurveyQuestions() as $qdata) {
407  $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($qdata["question_id"], $finished_ids);
408  $q_res = $q_eval->getResults();
409  $ov_rows = $q_eval->exportResults($q_res, $do_title, $do_label);
410 
411  switch ($_POST["export_format"]) {
412  case self::TYPE_XLS:
413  $excel->setActiveSheet(0);
414  foreach ($ov_rows as $row) {
415  foreach ($row as $col => $value) {
416  $excel->setCell($ov_row, $col, $value);
417  }
418  $ov_row++;
419  }
420  break;
421 
422  case self::TYPE_SPSS:
423  foreach ($ov_rows as $row) {
424  $csvfile[] = $row;
425  }
426  break;
427  }
428 
429  if ($details) {
430  switch ($_POST["export_format"]) {
431  case self::TYPE_XLS:
432  $this->exportResultsDetailsExcel($excel, $q_eval, $q_res, $do_title, $do_label);
433  break;
434  }
435  }
436  }
437 
438  // #11179
439  $type = !$details
440  ? $this->lng->txt("svy_eval_cumulated")
441  : $this->lng->txt("svy_eval_detail");
442 
443  $surveyname = $this->object->getTitle() . " " . $type . " " . date("Y-m-d");
444  $surveyname = preg_replace("/\s/", "_", trim($surveyname));
445  $surveyname = ilUtil::getASCIIFilename($surveyname);
446 
447  // send to client
448  switch ($_POST["export_format"]) {
449  case self::TYPE_XLS:
450  $excel->sendToClient($surveyname);
451  break;
452 
453  case self::TYPE_SPSS:
454  $csv = "";
455  $separator = ";";
456  foreach ($csvfile as $csvrow) {
457  $csvrow = $this->processCSVRow($csvrow, true, $separator);
458  $csv .= join($separator, $csvrow) . "\n";
459  }
460  ilUtil::deliverData($csv, $surveyname . ".csv");
461  exit();
462  break;
463  }
464  }
465 
475  protected function exportResultsDetailsExcel(ilExcel $a_excel, SurveyQuestionEvaluation $a_eval, $a_results, $a_do_title, $a_do_label)
476  {
477  $question_res = $a_results;
478  $matrix = false;
479  if (is_array($question_res)) {
480  $question_res = $question_res[0][1];
481  $matrix = true;
482  }
483  $question = $question_res->getQuestion();
484 
485  $a_excel->addSheet($question->getTitle());
486 
487 
488  // question "overview"
489 
490  $kv = array();
491 
492  if ($a_do_title) {
493  $kv[$this->lng->txt("title")] = $question->getTitle();
494  }
495  if ($a_do_label) {
496  $kv[$this->lng->txt("label")] = $question->label;
497  }
498 
499  // question
500  $kv[$this->lng->txt("question")] = $question->getQuestiontext();
501 
502  // question type
503  $kv[$this->lng->txt("question_type")] = SurveyQuestion::_getQuestionTypeName($question->getQuestionType());
504 
505  // :TODO: present subtypes (hrz/vrt, mc/sc mtx, metric scale)?
506 
507  // answered and skipped users
508  $kv[$this->lng->txt("users_answered")] = (int) $question_res->getUsersAnswered();
509  $kv[$this->lng->txt("users_skipped")] = (int) $question_res->getUsersSkipped(); // #0021671
510 
511  $excel_row = 1;
512 
513  foreach ($kv as $key => $value) {
514  $a_excel->setCell($excel_row, 0, $key);
515  $a_excel->setCell($excel_row++, 1, $value);
516  }
517 
518  if (!$matrix) {
519  $this->parseResultsToExcel(
520  $a_excel,
521  $question_res,
522  $excel_row,
523  $a_eval->getExportGrid($a_results),
524  $a_eval->getTextAnswers($a_results)
525  );
526  } else {
527  // question
528  $this->parseResultsToExcel(
529  $a_excel,
530  $question_res,
531  $excel_row,
532  null,
533  null,
534  false
535  );
536 
537  $texts = $a_eval->getTextAnswers($a_results);
538 
539  // "rows"
540  foreach ($a_results as $row_results) {
541  $row_title = $row_results[0];
542 
543  $a_excel->setCell($excel_row, 0, $this->lng->txt("row"));
544  $a_excel->setCell($excel_row++, 1, $row_title);
545 
546  $this->parseResultsToExcel(
547  $a_excel,
548  $row_results[1],
549  $excel_row,
550  $a_eval->getExportGrid($row_results[1]),
551  is_array($texts[$row_title])
552  ? array("" => $texts[$row_title])
553  : null
554  );
555  }
556  }
557 
558  // matrix question: overview #21438
559  if ($matrix) {
560  $a_excel->setCell($excel_row++, 0, $this->lng->txt("overview"));
561 
562  // title row with variables
563  $counter = 0;
564  $cats = $question->getColumns();
565  foreach ($cats->getCategories() as $cat) {
566  $a_excel->setColors($a_excel->getCoordByColumnAndRow(1 + $counter, $excel_row), ilSurveyEvaluationGUI::EXCEL_SUBTITLE);
567  $a_excel->setCell($excel_row, 1 + $counter, $cat->title);
568  $counter++;
569  }
570  $excel_row++;
571 
572  foreach ($a_results as $row_results) {
573  $row_title = $row_results[0];
574  $counter = 0;
575  $a_excel->setCell($excel_row, 0, $row_title);
576 
577  $vars = $row_results[1]->getVariables();
578  if ($vars) {
579  foreach ($vars as $var) {
580  $a_excel->setCell($excel_row, ++$counter, $var->abs);
581  }
582  }
583  $excel_row++;
584  }
585  }
586 
587  // 1st column is bold
588  $a_excel->setBold("A1:A" . $excel_row);
589  }
590 
591  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)
592  {
593  $kv = array();
594 
595  if ($a_include_mode) {
596  if ($a_results->getModeValue() !== null) {
597  // :TODO:
598  $kv[$this->lng->txt("mode")] = is_array($a_results->getModeValue())
599  ? implode(", ", $a_results->getModeValue())
600  : $a_results->getModeValue();
601 
602  $kv[$this->lng->txt("mode_text")] = $a_results->getModeValueAsText();
603  $kv[$this->lng->txt("mode_nr_of_selections")] = (int) $a_results->getModeNrOfSelections();
604  }
605 
606  if ($a_results->getMedian() !== null) {
607  $kv[$this->lng->txt("median")] = $a_results->getMedianAsText();
608  }
609 
610  if ($a_results->getMean() !== null) {
611  $kv[$this->lng->txt("arithmetic_mean")] = $a_results->getMean();
612  }
613  }
614 
615  foreach ($kv as $key => $value) {
616  $a_excel->setCell($a_excel_row, 0, $key);
617  $a_excel->setCell($a_excel_row++, 1, $value);
618  }
619 
620  // grid
621  if ($a_grid) {
622  // header
623  $a_excel->setColors("B" . $a_excel_row . ":E" . $a_excel_row, ilSurveyEvaluationGUI::EXCEL_SUBTITLE);
624  $a_excel->setCell($a_excel_row, 0, $this->lng->txt("categories"));
625  foreach ($a_grid["cols"] as $col_idx => $col) {
626  $a_excel->setCell($a_excel_row, $col_idx + 1, $col);
627  }
628  $a_excel_row++;
629 
630  // rows
631  foreach ($a_grid["rows"] as $cols) {
632  foreach ($cols as $col_idx => $col) {
633  $a_excel->setCell($a_excel_row, $col_idx + 1, $col);
634  }
635  $a_excel_row++;
636  }
637  }
638 
639  // text answers
640  if ($a_text_answers) {
641  // "given_answers" ?
642  $a_excel->setCell($a_excel_row, 0, $this->lng->txt("freetext_answers"));
643 
644  // mc/sc
645  if (!is_array($a_text_answers[""])) {
646  $a_excel->setColors("B" . $a_excel_row . ":C" . $a_excel_row, ilSurveyEvaluationGUI::EXCEL_SUBTITLE);
647  $a_excel->setCell($a_excel_row, 1, $this->lng->txt("title"));
648  $a_excel->setCell($a_excel_row++, 2, $this->lng->txt("answer"));
649  }
650  // mtx (row), txt
651  else {
652  $a_excel->setColors("B" . $a_excel_row . ":B" . $a_excel_row, ilSurveyEvaluationGUI::EXCEL_SUBTITLE);
653  $a_excel->setCell($a_excel_row++, 1, $this->lng->txt("answer"));
654  }
655 
656  foreach ($a_text_answers as $var => $items) {
657  foreach ($items as $item) {
658  if (!is_array($a_text_answers[""])) {
659  $a_excel->setCell($a_excel_row, 1, $var);
660  $a_excel->setCell($a_excel_row++, 2, $item);
661  } else {
662  $a_excel->setCell($a_excel_row++, 1, $item);
663  }
664  }
665  }
666  }
667  }
668 
669  public function exportData()
670  {
671  if (strlen($_POST["export_format"])) {
672  $this->exportCumulatedResults(0);
673  return;
674  } else {
675  $this->ctrl->redirect($this, 'evaluation');
676  }
677  }
678 
679  public function exportDetailData()
680  {
681  if (strlen($_POST["export_format"])) {
682  $this->exportCumulatedResults(1);
683  return;
684  } else {
685  $this->ctrl->redirect($this, 'evaluation');
686  }
687  }
688 
689  public function printEvaluation()
690  {
691  ilUtil::sendInfo($this->lng->txt('use_browser_print_function'), true);
692  $this->ctrl->redirect($this, 'evaluation');
693  }
694 
695  protected function buildExportModal($a_id, $a_cmd)
696  {
697  $tpl = $this->tpl;
698 
699  $form_id = "svymdfrm";
700 
701  // hide modal on form submit
702  $tpl->addOnLoadCode('$("#form_' . $form_id . '").submit(function() { $("#' . $a_id . '").modal("hide"); });');
703 
704  $modal = ilModalGUI::getInstance();
705  $modal->setId($a_id);
706  $modal->setHeading(($this->lng->txt("svy_export_format")));
707 
708  $form = new ilPropertyFormGUI();
709  $form->setId($form_id);
710  $form->setFormAction($this->ctrl->getFormAction($this, $a_cmd));
711 
712  $format = new ilSelectInputGUI($this->lng->txt("filetype"), "export_format");
713  $format->setOptions(array(
714  self::TYPE_XLS => $this->lng->txt('exp_type_excel'),
715  self::TYPE_SPSS => $this->lng->txt('exp_type_csv')
716  ));
717  $form->addItem($format, true);
718 
719  $label = new ilSelectInputGUI($this->lng->txt("title"), "export_label");
720  $label->setOptions(array(
721  'label_only' => $this->lng->txt('export_label_only'),
722  'title_only' => $this->lng->txt('export_title_only'),
723  'title_label' => $this->lng->txt('export_title_label')
724  ));
725  $form->addItem($label);
726 
727  $form->addCommandButton($a_cmd, $this->lng->txt("export"));
728  $form->setPreventDoubleSubmission(false);
729 
730  $modal->setBody($form->getHTML());
731 
732  return $modal->getHTML();
733  }
734 
735  public function evaluation($details = 0, $pdf = false, $return_pdf = false)
736  {
737  $ilToolbar = $this->toolbar;
738  $tree = $this->tree;
739  $ui = $this->ui;
740 
741  $ui_factory = $ui->factory();
742  $ui_renderer = $ui->renderer();
743 
744  $this->lng->loadLanguageModule("survey");
745 
746  $this->log->debug("check access");
747 
748  // auth
749  if (!$this->hasResultsAccess()) {
750  if (!$this->access->checkAccess('read', '', $this->object->getRefId())) {
751  ilUtil::sendFailure($this->lng->txt("permission_denied"));
752  return;
753  }
754  switch ($this->object->getEvaluationAccess()) {
756  ilUtil::sendFailure($this->lng->txt("permission_denied"));
757  return;
758 
761  if (!$this->checkAnonymizedEvaluationAccess()) {
762  ilUtil::sendFailure($this->lng->txt("permission_denied"));
763  return;
764  }
765  break;
766  }
767  }
768 
769  $this->log->debug("check access ok");
770 
771  // setup toolbar
772 
773  if (!$pdf) {
774  $ilToolbar->setFormAction($this->ctrl->getFormAction($this));
775  if ($this->object->get360Mode()) {
776  $appr_id = $this->getAppraiseeId();
777  $this->addApprSelectionToToolbar();
778  }
779  }
780  $results = array();
781 
782  $eval_tpl = new ilTemplate("tpl.il_svy_svy_evaluation.html", true, true, "Modules/Survey");
783 
784  if (!$this->object->get360Mode() || $appr_id) {
785  if ($details) {
786  $captions = new ilSelectInputGUI($this->lng->txt("svy_eval_captions"), "cp");
787  $captions->setOptions(array(
788  "ap" => $this->lng->txt("svy_eval_captions_abs_perc"),
789  "a" => $this->lng->txt("svy_eval_captions_abs"),
790  "p" => $this->lng->txt("svy_eval_captions_perc")
791  ));
792  $captions->setValue($_POST["cp"]);
793  $ilToolbar->addInputItem($captions, true);
794 
795  $view = new ilSelectInputGUI($this->lng->txt("svy_eval_view"), "vw");
796  $view->setOptions(array(
797  "tc" => $this->lng->txt("svy_eval_view_tables_charts"),
798  "t" => $this->lng->txt("svy_eval_view_tables"),
799  "c" => $this->lng->txt("svy_eval_view_charts")
800  ));
801  $view->setValue($_POST["vw"]);
802  $ilToolbar->addInputItem($view, true);
803 
804  $button = ilSubmitButton::getInstance();
805  $button->setCaption("ok");
806  $button->setCommand("evaluationdetails");
807  $button->setOmitPreventDoubleSubmission(true);
808  $ilToolbar->addButtonInstance($button);
809 
810  $ilToolbar->addSeparator();
811 
812  //templates: results, table of contents
813  $dtmpl = new ilTemplate("tpl.il_svy_svy_results_details.html", true, true, "Modules/Survey");
814  $toc_tpl = new ilTemplate("tpl.svy_results_table_contents.html", true, true, "Modules/Survey");
815  $this->lng->loadLanguageModule("content");
816  $toc_tpl->setVariable("TITLE_TOC", $this->lng->txt('cont_toc'));
817  }
818 
819  if (!$pdf) {
820  $modal_id = "svy_ev_exp";
821  $modal = $this->buildExportModal($modal_id, $details
822  ? 'exportDetailData'
823  : 'exportData');
824 
825  $button = ilLinkButton::getInstance();
826  $button->setCaption("export");
827  $button->setOnClick('$(\'#' . $modal_id . '\').modal(\'show\')');
828  $ilToolbar->addButtonInstance($button);
829 
830  $ilToolbar->addSeparator();
831 
832  $button = ilLinkButton::getInstance();
833  $button->setCaption("print");
834  $button->setOnClick("if(il.Accordion) { il.Accordion.preparePrint(); } window.print(); return false;");
835  $button->setOmitPreventDoubleSubmission(true);
836  $ilToolbar->addButtonInstance($button);
837 
838  // patch BGHW jluetzen-ilias
839  $this->ctrl->setParameter($this, "cp", $_POST["cp"]);
840  $this->ctrl->setParameter($this, "vw", $_POST["vw"]);
841  $url = $this->ctrl->getLinkTarget($this, $details
842  ? "evaluationdetailspdf"
843  : "evaluationpdf");
844  $this->ctrl->setParameter($this, "cp", "");
845  $this->ctrl->setParameter($this, "vw", "");
846  $button = ilLinkButton::getInstance();
847  $button->setCaption("svy_export_pdf");
848  $button->setUrl($url);
849  $button->setOmitPreventDoubleSubmission(true);
850  $ilToolbar->addButtonInstance($button);
851  }
852 
853  $finished_ids = null;
854  if ($appr_id) {
855  $finished_ids = $this->object->getFinishedIdsForAppraiseeId($appr_id);
856  if (!sizeof($finished_ids)) {
857  $finished_ids = array(-1);
858  }
859  }
860 
861  // filter own self evaluation, if option set and no write permission
862  if (!$this->access->checkAccess('write', '', $this->object->getRefId())
863  && $this->object->getMode() == ilObjSurvey::MODE_SELF_EVAL
864  && $this->object->getSelfEvaluationResults() == ilObjSurvey::RESULTS_SELF_EVAL_OWN) {
865  $finished_ids = $this->object->getFinishedIdsForSelfEval($this->user->getId());
866  }
867 
868  $details_figure = $_POST["cp"]
869  ? $_POST["cp"]
870  : "ap";
871  $details_view = $_POST["vw"]
872  ? $_POST["vw"]
873  : "tc";
874 
875  // @todo
876  // filter finished ids
877  $finished_ids2 = $this->access->filterUserIdsByRbacOrPositionOfCurrentUser(
878  'read_results',
879  'access_results',
880  $this->object->getRefId(),
881  (array) $finished_ids
882  );
883 
884  // parse answer data in evaluation results
885  $list = new ilNestedList();
886 
887  foreach ($this->object->getSurveyQuestions() as $qdata) {
888  $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($qdata["question_id"], $finished_ids);
889  $q_res = $q_eval->getResults();
890  $results[] = $q_res;
891 
892  if ($details) {
893  $this->renderDetails($details_view, $details_figure, $qdata, $q_eval, $q_res, $pdf);
894 
895  // TABLE OF CONTENTS
896  if ($qdata["questionblock_id"] &&
897  $qdata["questionblock_id"] != $this->last_questionblock_id) {
898  $qblock = ilObjSurvey::_getQuestionblock($qdata["questionblock_id"]);
899  if ($qblock["show_blocktitle"]) {
900  $list->addListNode($qdata["questionblock_title"], "q" . $qdata["questionblock_id"]);
901  } else {
902  $list->addListNode("", "q" . $qdata["questionblock_id"]);
903  }
904  $this->last_questionblock_id = $qdata["questionblock_id"];
905  }
906  $anchor_id = "svyrdq" . $qdata["question_id"];
907  $list->addListNode("<a href='#" . $anchor_id . "'>" . $qdata["title"] . "</a>", $qdata["question_id"], $qdata["questionblock_id"] ?
908  "q" . $qdata["questionblock_id"] : 0);
909  }
910  }
911 
912  if ($details) {
913  $list->setListClass("il_Explorer");
914  $toc_tpl->setVariable("LIST", $list->getHTML());
915 
916  //TABLE OF CONTENTS
917  $panel_toc = $ui_factory->panel()->standard("", $ui_factory->legacy($toc_tpl->get()));
918  $render_toc = $ui_renderer->render($panel_toc);
919  $dtmpl->setVariable("PANEL_TOC", $render_toc);
920 
921  //REPORT
922  $report_title = "";
923  $panel_report = $ui_factory->panel()->report($report_title, $this->array_panels);
924  $render_report = $ui_renderer->render($panel_report);
925  $dtmpl->setVariable("PANEL_REPORT", $render_report);
926 
927  //print the main template
928  $eval_tpl->setVariable('DETAIL', $dtmpl->get());
929  }
930  }
931 
932  $eval_tpl->setVariable('MODAL', $modal);
933  if (!$details) {
934  $table_gui = new ilSurveyResultsCumulatedTableGUI($this, $details ? 'evaluationdetails' : 'evaluation', $results);
935  $eval_tpl->setVariable('CUMULATED', $table_gui->getHTML());
936  }
937  unset($dtmpl);
938  unset($table_gui);
939  unset($modal);
940 
941 
942  //
943  // print header
944  //
945 
946  $path = "";
947  $path_full = $tree->getPathFull($this->object->getRefId());
948  foreach ($path_full as $data) {
949  $path .= " &raquo; ";
950  $path .= $data['title'];
951  }
952 
954  $props = array(
955  $this->lng->txt("link") => ilLink::_getStaticLink($this->object->getRefId()),
956  $this->lng->txt("path") => $path,
957  $this->lng->txt("svy_results") => !$details
958  ? $this->lng->txt("svy_eval_cumulated")
959  : $this->lng->txt("svy_eval_detail"),
960  $this->lng->txt("date") => ilDatePresentation::formatDate(new ilDateTime(time(), IL_CAL_UNIX)),
961  );
962  $eval_tpl->setCurrentBlock("print_header_bl");
963  foreach ($props as $key => $value) {
964  $eval_tpl->setVariable("HEADER_PROP_KEY", $key);
965  $eval_tpl->setVariable("HEADER_PROP_VALUE", $value);
966  $eval_tpl->parseCurrentBlock();
967  }
968 
969  $this->log->debug("end");
970 
971  $this->tpl->setContent($eval_tpl->get());
972 
973  if ($pdf) {
974  $this->tpl->setTitle($this->object->getTitle());
975  $this->tpl->setTitleIcon(
976  ilObject::_getIcon("", "big", $this->object->getType()),
977  $this->lng->txt("obj_" . $this->object->getType())
978  );
979  $this->tpl->setDescription($this->object->getDescription());
980 
981 
982  $html = $this->tpl->printToString();
983 
984  if ($return_pdf) {
985  return $html;
986  } else {
987  $this->generateAndSendPDF($html);
988  }
989  }
990 
991  // $this->tpl->addCss("./Modules/Survey/templates/default/survey_print.css", "print");
992  }
993 
1004  //protected function renderDetails($a_details_parts, $a_details_figure, ilTemplate $a_tpl, array $a_qdata, SurveyQuestionEvaluation $a_eval, $a_results)
1005  protected function renderDetails($a_details_parts, $a_details_figure, array $a_qdata, SurveyQuestionEvaluation $a_eval, $a_results, $pdf)
1006  {
1007  $ui_factory = $this->ui->factory();
1008  $a_tpl = new ilTemplate("tpl.svy_results_details_panel.html", true, true, "Modules/Survey");
1009 
1010  $question_res = $a_results;
1011  $matrix = false;
1012  if (is_array($question_res)) {
1013  $question_res = $question_res[0][1];
1014  $matrix = true;
1015  }
1016 
1017  // see #28507 (matrix question without a row)
1018  if (!is_object($question_res)) {
1019  return;
1020  }
1021 
1022  $question = $question_res->getQuestion();
1023 
1024  // question "overview"
1025 
1026  // :TODO: present subtypes (hrz/vrt, mc/sc mtx)?
1027 
1028  $a_tpl->setVariable("QTYPE", SurveyQuestion::_getQuestionTypeName($question->getQuestionType()));
1029 
1030  $kv = array();
1031  $kv["users_answered"] = $question_res->getUsersAnswered();
1032  $kv["users_skipped"] = $question_res->getUsersSkipped();
1033 
1034  if (!$matrix) {
1035  if ($question_res->getModeValue() !== null) {
1036  $kv["mode"] = wordwrap($question_res->getModeValueAsText(), 50, "<br />");
1037  $kv["mode_nr_of_selections"] = $question_res->getModeNrOfSelections();
1038  }
1039  if ($question_res->getMedian() !== null) {
1040  $kv["median"] = $question_res->getMedianAsText();
1041  }
1042  if ($question_res->getMean() !== null) {
1043  $kv["arithmetic_mean"] = $question_res->getMean();
1044  }
1045  }
1046 
1047  $svy_type_title = SurveyQuestion::_getQuestionTypeName($question->getQuestionType());
1048  $qst_title = $question->getTitle();
1049  $svy_text = nl2br($question->getQuestiontext());
1050  $card_table_tpl = new ilTemplate("tpl.svy_results_details_card.html", true, true, "Modules/Survey");
1051  foreach ($kv as $key => $value) {
1052  $card_table_tpl->setCurrentBlock("question_statistics_card");
1053  $card_table_tpl->setVariable("QUESTION_STATISTIC_KEY", $this->lng->txt($key));
1054  $card_table_tpl->setVariable("QUESTION_STATISTIC_VALUE", $value);
1055  $card_table_tpl->parseCurrentBlock();
1056  }
1057 
1058  // patch BGHW: added anchor
1059  $anchor_id = "svyrdq" . $question->getId();
1060  $title = "<span id='$anchor_id'>$qst_title</span>";
1061  $panel_qst_card = $ui_factory->panel()->sub($title, $ui_factory->legacy($svy_text))
1062  ->withCard($ui_factory->card()->standard($svy_type_title)->withSections(array($ui_factory->legacy($card_table_tpl->get()))));
1063 
1064  array_push($this->array_panels, $panel_qst_card);
1065 
1066  // grid
1067  if ($a_details_parts == "t" ||
1068  $a_details_parts == "tc") {
1069  $grid = $a_eval->getGrid(
1070  $a_results,
1071  ($a_details_figure == "ap" || $a_details_figure == "a"),
1072  ($a_details_figure == "ap" || $a_details_figure == "p")
1073  );
1074  if ($grid) {
1075  foreach ($grid["cols"] as $col) {
1076  $a_tpl->setCurrentBlock("grid_col_header_bl");
1077  $a_tpl->setVariable("COL_HEADER", $col);
1078  $a_tpl->parseCurrentBlock();
1079  }
1080  foreach ($grid["rows"] as $cols) {
1081  foreach ($cols as $idx => $col) {
1082  if ($idx > 0) {
1083  $a_tpl->touchBlock("grid_col_nowrap_bl");
1084  }
1085 
1086  $a_tpl->setCurrentBlock("grid_col_bl");
1087  $a_tpl->setVariable("COL_CAPTION", trim($col));
1088  $a_tpl->parseCurrentBlock();
1089  }
1090 
1091  $a_tpl->touchBlock("grid_row_bl");
1092  }
1093  }
1094  }
1095 
1096  // text answers
1097  $texts = $a_eval->getTextAnswers($a_results);
1098  if ($texts) {
1099  if (array_key_exists("", $texts)) {
1100  $a_tpl->setVariable("TEXT_HEADING", $this->lng->txt("given_answers"));
1101  foreach ($texts[""] as $item) {
1102  $a_tpl->setCurrentBlock("text_direct_item_bl");
1103  $a_tpl->setVariable("TEXT_DIRECT", nl2br(htmlentities($item)));
1104  $a_tpl->parseCurrentBlock();
1105  }
1106  } else {
1107  $acc = new ilAccordionGUI();
1108  // patch BGHW: fixed accordion in pdf output
1109  if ($_GET["pdf"] == 1) {
1110  $acc->setBehaviour(ilAccordionGUI::FORCE_ALL_OPEN);
1111  }
1112  $acc->setId("svyevaltxt" . $question->getId());
1113 
1114  $a_tpl->setVariable("TEXT_HEADING", $this->lng->txt("freetext_answers"));
1115 
1116  foreach ($texts as $var => $items) {
1117  $list = array("<ul class=\"small\">");
1118  foreach ($items as $item) {
1119  $list[] = "<li>" . nl2br(htmlentities($item)) . "</li>";
1120  }
1121  $list[] = "</ul>";
1122  $acc->addItem($var, implode("\n", $list));
1123  }
1124 
1125  $a_tpl->setVariable("TEXT_ACC", $acc->getHTML());
1126  }
1127  }
1128 
1129  // chart
1130  if ($a_details_parts == "c" ||
1131  $a_details_parts == "tc") {
1132  $chart = $a_eval->getChart($a_results);
1133  if ($chart) {
1134  if (is_array($chart)) {
1135  // legend
1136  if (is_array($chart[1])) {
1137  foreach ($chart[1] as $legend_item) {
1138  $r = hexdec(substr($legend_item[1], 1, 2));
1139  $g = hexdec(substr($legend_item[1], 3, 2));
1140  $b = hexdec(substr($legend_item[1], 5, 2));
1141 
1142  $a_tpl->setCurrentBlock("legend_bl");
1143  $a_tpl->setVariable("LEGEND_CAPTION", $legend_item[0]);
1144  $a_tpl->setVariable("LEGEND_COLOR", $legend_item[1]);
1145  $a_tpl->setVariable("LEGEND_COLOR_SVG", $r . "," . $g . "," . $b);
1146  $a_tpl->parseCurrentBlock();
1147  }
1148  }
1149 
1150  $chart = $chart[0];
1151  }
1152 
1153  // patch BGHW jluezen
1154  if (!$pdf) {
1155  $this->ctrl->setParameter($this, "qid", $question->getId());
1156  $url = $this->ctrl->getLinkTarget($this, "downloadChart");
1157  $this->ctrl->setParameter($this, "qid", "");
1158  }
1159 
1160  $a_tpl->setVariable("CHART", $chart);
1161  $a_tpl->setVariable("CHART_DL_URL", $url);
1162  $a_tpl->setVariable("CHART_DL_TXT", $this->lng->txt("svy_chart_download"));
1163  }
1164  }
1165 
1166  $panel = $ui_factory->panel()->sub("", $ui_factory->legacy($a_tpl->get()));
1167  array_push($this->array_panels, $panel);
1168  }
1169 
1176  public function addApprSelectionToToolbar()
1177  {
1178  $ilToolbar = $this->toolbar;
1180 
1181  $svy_mode = $this->object->getMode();
1182  if ($svy_mode == ilObjSurvey::MODE_360 || $svy_mode == ilObjSurvey::MODE_SELF_EVAL) {
1183  $appr_id = $this->getAppraiseeId();
1184 
1185  $options = array();
1186  if (!$appr_id) {
1187  $options[""] = $this->lng->txt("please_select");
1188  }
1189 
1190  $no_appr = true;
1191  if ($this->object->get360Mode()) {
1192  foreach ($this->object->getAppraiseesData() as $item) {
1193  if ($item["closed"]) {
1194  $options[$item["user_id"]] = $item["login"];
1195  $no_appr = false;
1196  }
1197  }
1198  } else { //self evaluation mode
1199  foreach ($this->object->getSurveyParticipants() as $item) {
1200  $options[ilObjUser::_lookupId($item['login'])] = $item['login'];
1201  $no_appr = false;
1202  }
1203  }
1204 
1205  if (!$no_appr) {
1206  if ($rbacsystem->checkAccess("write", $this->object->getRefId()) ||
1207  $this->object->get360Results() == ilObjSurvey::RESULTS_360_ALL ||
1208  $this->object->getSelfEvaluationResults() == ilObjSurvey::RESULTS_SELF_EVAL_ALL) {
1209  $appr = new ilSelectInputGUI($this->lng->txt("svy_participant"), "appr_id");
1210  $appr->setOptions($options);
1211  $appr->setValue($this->getAppraiseeId());
1212  $ilToolbar->addInputItem($appr, true);
1213 
1214  $button = ilSubmitButton::getInstance();
1215  $button->setCaption("survey_360_select_appraisee");
1216  $button->setCommand($this->ctrl->getCmd());
1217  $ilToolbar->addButtonInstance($button);
1218 
1219  if ($appr_id) {
1220  $ilToolbar->addSeparator();
1221  }
1222  }
1223  } else {
1224  ilUtil::sendFailure($this->lng->txt("survey_360_no_closed_appraisees"));
1225  }
1226  }
1227  }
1228 
1239  public function processCSVRow($row, $quoteAll = false, $separator = ";")
1240  {
1241  $resultarray = array();
1242  foreach ($row as $rowindex => $entry) {
1243  if (is_array($entry)) {
1244  $entry = implode("/", $entry);
1245  }
1246  $surround = false;
1247  if ($quoteAll) {
1248  $surround = true;
1249  }
1250  if (strpos($entry, "\"") !== false) {
1251  $entry = str_replace("\"", "\"\"", $entry);
1252  $surround = true;
1253  }
1254  if (strpos($entry, $separator) !== false) {
1255  $surround = true;
1256  }
1257  // replace all CR LF with LF (for Excel for Windows compatibility
1258  $entry = str_replace(chr(13) . chr(10), chr(10), $entry);
1259  if ($surround) {
1260  $resultarray[$rowindex] = utf8_decode("\"" . $entry . "\"");
1261  } else {
1262  $resultarray[$rowindex] = utf8_decode($entry);
1263  }
1264  }
1265  return $resultarray;
1266  }
1267 
1268 
1269  public function exportEvaluationUser()
1270  {
1271  // build title row(s)
1272 
1273  $title_row = $title_row2 = array();
1274  $title_row[] = $this->lng->txt("lastname"); // #12756
1275  $title_row[] = $this->lng->txt("firstname");
1276  $title_row[] = $this->lng->txt("login");
1277  $title_row[] = $this->lng->txt('workingtime'); // #13622
1278  $title_row[] = $this->lng->txt('survey_results_finished');
1279  $title_row2[] = "";
1280  $title_row2[] = "";
1281  $title_row2[] = "";
1282  $title_row2[] = "";
1283  $title_row2[] = "";
1284  if ($this->object->canExportSurveyCode()) {
1285  $title_row[] = $this->lng->txt("codes");
1286  $title_row2[] = "";
1287  }
1288 
1289  $questions = array();
1290 
1291  foreach ($this->object->getSurveyQuestions() as $qdata) {
1292  $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($qdata["question_id"], $finished_ids);
1293  $q_res = $q_eval->getResults();
1294 
1295  $questions[$qdata["question_id"]] = array($q_eval, $q_res);
1296 
1297  $question = is_array($q_res)
1298  ? $q_res[0][1]->getQuestion()
1299  : $q_res->getQuestion();
1300 
1301  $do_title = $do_label = true;
1302  switch ($_POST['export_label']) {
1303  case "label_only":
1304  $title_row[] = $question->label;
1305  $title_row2[] = "";
1306  $do_title = false;
1307  break;
1308 
1309  case "title_only":
1310  $title_row[] = $question->getTitle();
1311  $title_row2[] = "";
1312  $do_label = false;
1313  break;
1314 
1315  default:
1316  $title_row[] = $question->getTitle();
1317  $title_row2[] = $question->label;
1318  break;
1319  }
1320 
1321  $q_eval->getUserSpecificVariableTitles($title_row, $title_row2, $do_title, $do_label);
1322  }
1323 
1324  $rows = array();
1325 
1326  // add title row(s)
1327  $rows[] = $title_row;
1328  if (implode("", $title_row2)) {
1329  $rows[] = $title_row2;
1330  }
1331 
1332  // #13620
1334 
1335  $finished_ids = null;
1336  if ($this->object->get360Mode()) {
1337  $appr_id = $_REQUEST["appr_id"];
1338  if (!$appr_id) {
1339  $this->ctrl->redirect($this, "evaluationuser");
1340  }
1341  $finished_ids = $this->object->getFinishedIdsForAppraiseeId($appr_id);
1342  if (!sizeof($finished_ids)) {
1343  $finished_ids = array(-1);
1344  }
1345  }
1346 
1347  //$participants = $this->object->getSurveyParticipants($finished_ids);
1348  $participants = $this->filterSurveyParticipantsByAccess($finished_ids);
1349 
1350  foreach ($participants as $user) {
1351  $user_id = $user["active_id"];
1352 
1353  $row = array();
1354  $row[] = trim($user["lastname"])
1355  ? $user["lastname"]
1356  : $user["name"]; // anonymous
1357  $row[] = $user["firstname"];
1358  $row[] = $user["login"]; // #10579
1359 
1360  if ($this->object->canExportSurveyCode()) {
1361  $row[] = $user_id;
1362  }
1363 
1364  $row[] = $this->object->getWorkingtimeForParticipant($user_id);
1365 
1366  if ((bool) $user["finished"]) {
1367  $dt = new ilDateTime($user["finished_tstamp"], IL_CAL_UNIX);
1368  $row[] = ($_POST["export_format"] == self::TYPE_XLS)
1369  ? $dt
1371  } else {
1372  $row[] = "-"; // :TODO:
1373  }
1374 
1375  foreach ($questions as $item) {
1376  $q_eval = $item[0];
1377  $q_res = $item[1];
1378 
1379  $q_eval->addUserSpecificResults($row, $user_id, $q_res);
1380  }
1381 
1382  $rows[] = $row;
1383  }
1384 
1385  // #11179
1386  $surveyname = $this->object->getTitle() . " " . $this->lng->txt("svy_eval_user") . " " . date("Y-m-d");
1387  $surveyname = preg_replace("/\s/", "_", trim($surveyname));
1388  $surveyname = ilUtil::getASCIIFilename($surveyname);
1389 
1390  switch ($_POST["export_format"]) {
1391  case self::TYPE_XLS:
1392  $excel = new ilExcel();
1393  $excel->addSheet($this->lng->txt("svy_eval_user"));
1394 
1395  foreach ($rows as $row_idx => $row) {
1396  foreach ($row as $col_idx => $col) {
1397  $excel->setCell($row_idx + 1, $col_idx, $col);
1398  }
1399  if (!$row_idx) {
1400  $excel->setBold("A1:" . $excel->getColumnCoord(sizeof($row) - 1) . "1");
1401  }
1402  }
1403  $excel->sendToClient($surveyname);
1404 
1405  // no break
1406  case self::TYPE_SPSS:
1407  $csv = "";
1408  $separator = ";";
1409  foreach ($rows as $csvrow) {
1410  $csvrow = str_replace("\n", " ", $this->processCSVRow($csvrow, true, $separator));
1411  $csv .= join($separator, $csvrow) . "\n";
1412  }
1413  ilUtil::deliverData($csv, "$surveyname.csv");
1414  exit();
1415  }
1416  }
1417 
1425  public function evaluationuser()
1426  {
1427  $ilAccess = $this->access;
1428  $ilToolbar = $this->toolbar;
1429 
1430  if (!$this->hasResultsAccess() &&
1431  $this->object->getMode() != ilObjSurvey::MODE_SELF_EVAL) {
1432  ilUtil::sendFailure($this->lng->txt("no_permission"), true);
1433  $this->ctrl->redirectByClass("ilObjSurveyGUI", "infoScreen");
1434  }
1435 
1436  $ilToolbar->setFormAction($this->ctrl->getFormAction($this, "evaluationuser"));
1437 
1438  if ($this->object->get360Mode()) {
1439  $appr_id = $this->getAppraiseeId();
1440  $this->addApprSelectionToToolbar();
1441  }
1442 
1443  $tabledata = null;
1444  if (!$this->object->get360Mode() || $appr_id) {
1445  $modal_id = "svy_ev_exp";
1446  $modal = $this->buildExportModal($modal_id, "exportevaluationuser");
1447 
1448  $button = ilLinkButton::getInstance();
1449  $button->setCaption("export");
1450  $button->setOnClick('$(\'#' . $modal_id . '\').modal(\'show\')');
1451  $ilToolbar->addButtonInstance($button);
1452 
1453  $ilToolbar->addSeparator();
1454 
1455  $button = ilLinkButton::getInstance();
1456  $button->setCaption("print");
1457  $button->setOnClick("window.print(); return false;");
1458  $button->setOmitPreventDoubleSubmission(true);
1459  $ilToolbar->addButtonInstance($button);
1460 
1461  $finished_ids = null;
1462  if ($appr_id) {
1463  $finished_ids = $this->object->getFinishedIdsForAppraiseeId($appr_id);
1464  if (!sizeof($finished_ids)) {
1465  $finished_ids = array(-1);
1466  }
1467  }
1468 
1469  $data = $this->parseUserSpecificResults($finished_ids);
1470  }
1471 
1472  $table_gui = new ilSurveyResultsUserTableGUI($this, 'evaluationuser', $this->object->hasAnonymizedResults());
1473  $table_gui->setData($data);
1474  $this->tpl->setContent($table_gui->getHTML() . $modal);
1475  }
1476 
1477  protected function filterSurveyParticipantsByAccess($a_finished_ids)
1478  {
1479  $all_participants = $this->object->getSurveyParticipants($a_finished_ids);
1480  $participant_ids = [];
1481  foreach ($all_participants as $participant) {
1482  $participant_ids[] = $participant['usr_id'];
1483  }
1484 
1485 
1486  $filtered_participant_ids = $this->access->filterUserIdsByRbacOrPositionOfCurrentUser(
1487  'read_results',
1488  'access_results',
1489  $this->object->getRefId(),
1490  $participant_ids
1491  );
1492  $participants = [];
1493  foreach ($all_participants as $username => $user_data) {
1494  if (!$user_data['usr_id']) {
1495  $participants[$username] = $user_data;
1496  }
1497  if (in_array($user_data['usr_id'], $filtered_participant_ids)) {
1498  $participants[$username] = $user_data;
1499  }
1500  }
1501  return $participants;
1502  }
1503 
1504 
1505 
1506  protected function parseUserSpecificResults(array $a_finished_ids = null)
1507  {
1508  $data = array();
1509 
1510  $participants = $this->filterSurveyParticipantsByAccess($a_finished_ids);
1511 
1512  foreach ($this->object->getSurveyQuestions() as $qdata) {
1513  $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($qdata["question_id"], $a_finished_ids);
1514  $q_res = $q_eval->getResults();
1515 
1516  // see #28507 (matrix question without a row)
1517  if (is_array($q_res) && !is_object($q_res[0][1])) {
1518  continue;
1519  }
1520 
1521  $question = is_array($q_res)
1522  ? $q_res[0][1]->getQuestion()
1523  : $q_res->getQuestion();
1524 
1525  foreach ($participants as $user) {
1526  $user_id = $user["active_id"];
1527 
1528  $parsed_results = $q_eval->parseUserSpecificResults($q_res, $user_id);
1529 
1530  if (!array_key_exists($user_id, $data)) {
1531  $wt = $this->object->getWorkingtimeForParticipant($user_id);
1532 
1533  $finished = $user["finished"]
1534  ? $user["finished_tstamp"]
1535  : false;
1536 
1537  $data[$user_id] = array(
1538  "username" => $user["sortname"],
1539  "question" => $question->getTitle(),
1540  "results" => $parsed_results,
1541  "workingtime" => $wt,
1542  "finished" => $finished,
1543  "subitems" => array()
1544  );
1545  } else {
1546  $data[$user_id]["subitems"][] = array(
1547  "username" => " ",
1548  "question" => $question->getTitle(),
1549  "results" => $parsed_results,
1550  "workingtime" => null,
1551  "finished" => null
1552  );
1553  }
1554  }
1555  }
1556 
1557  return $data;
1558  }
1559 
1566  public function competenceEval()
1567  {
1568  $ilUser = $this->user;
1569  $lng = $this->lng;
1570  $ilCtrl = $this->ctrl;
1571  $ilToolbar = $this->toolbar;
1572  $tpl = $this->tpl;
1573  $ilTabs = $this->tabs;
1574 
1575  $survey = $this->object;
1576 
1577  $ilTabs->activateSubtab("svy_eval_competences");
1578  $ilTabs->activateTab("svy_results");
1579 
1580  $ilToolbar->setFormAction($this->ctrl->getFormAction($this, "competenceEval"));
1581 
1582  if ($this->object->get360Mode() || $survey->getMode() == ilObjSurvey::MODE_SELF_EVAL) {
1583  $appr_id = $this->getAppraiseeId();
1584  $this->addApprSelectionToToolbar();
1585  }
1586 
1587  if ($appr_id == 0) {
1588  return;
1589  }
1590 
1591  // evaluation modes
1592  $eval_modes = array();
1593 
1594  // get all competences of survey
1595  $sskill = new ilSurveySkill($survey);
1596  $opts = $sskill->getAllAssignedSkillsAsOptions();
1597  $skills = array();
1598  foreach ($opts as $id => $o) {
1599  $idarr = explode(":", $id);
1600  $skills[$id] = array("id" => $id, "title" => $o, "profiles" => array(),
1601  "base_skill" => $idarr[0], "tref_id" => $idarr[1]);
1602  }
1603 
1604  // get matching user competence profiles
1605  // -> add gap analysis to profile
1607  foreach ($profiles as $p) {
1608  $prof = new ilSkillProfile($p["id"]);
1609  $prof_levels = $prof->getSkillLevels();
1610  foreach ($prof_levels as $pl) {
1611  if (isset($skills[$pl["base_skill_id"] . ":" . $pl["tref_id"]])) {
1612  $skills[$pl["base_skill_id"] . ":" . $pl["tref_id"]]["profiles"][] =
1613  $p["id"];
1614 
1615  $eval_modes["gap_" . $p["id"]] =
1616  $lng->txt("svy_gap_analysis") . ": " . $prof->getTitle();
1617  }
1618  }
1619  }
1620  //var_dump($skills);
1621  //var_dump($eval_modes);
1622 
1623  // if one competence does not match any profiles
1624  // -> add "competences of survey" alternative
1625  reset($skills);
1626  foreach ($skills as $sk) {
1627  if (count($sk["profiles"]) == 0) {
1628  $eval_modes["skills_of_survey"] = $lng->txt("svy_all_survey_competences");
1629  }
1630  }
1631 
1632  // final determination of current evaluation mode
1633  $comp_eval_mode = $_GET["comp_eval_mode"];
1634  if ($_POST["comp_eval_mode"] != "") {
1635  $comp_eval_mode = $_POST["comp_eval_mode"];
1636  }
1637 
1638  if (!isset($eval_modes[$comp_eval_mode])) {
1639  reset($eval_modes);
1640  $comp_eval_mode = key($eval_modes);
1641  $ilCtrl->setParameter($this, "comp_eval_mode", $comp_eval_mode);
1642  }
1643 
1644  $ilCtrl->saveParameter($this, "comp_eval_mode");
1645 
1646  $mode_sel = new ilSelectInputGUI($lng->txt("svy_analysis"), "comp_eval_mode");
1647  $mode_sel->setOptions($eval_modes);
1648  $mode_sel->setValue($comp_eval_mode);
1649  $ilToolbar->addInputItem($mode_sel, true);
1650 
1651  $ilToolbar->addFormButton($lng->txt("select"), "competenceEval");
1652 
1653  if (substr($comp_eval_mode, 0, 4) == "gap_") {
1654  // gap analysis
1655  $profile_id = (int) substr($comp_eval_mode, 4);
1656 
1657  $pskills_gui = new ilPersonalSkillsGUI();
1658  $pskills_gui->setProfileId($profile_id);
1659  $pskills_gui->setGapAnalysisActualStatusModePerObject($survey->getId(), $lng->txt("skmg_eval_type_1"));
1660  if ($survey->getFinishedIdForAppraiseeIdAndRaterId($appr_id, $appr_id) > 0) {
1661  $sskill = new ilSurveySkill($survey);
1662  $self_levels = array();
1663  foreach ($sskill->determineSkillLevelsForAppraisee($appr_id, true) as $sl) {
1664  $self_levels[$sl["base_skill_id"]][$sl["tref_id"]] = $sl["new_level_id"];
1665  }
1666  $pskills_gui->setGapAnalysisSelfEvalLevels($self_levels);
1667  }
1668  $html = $pskills_gui->getGapAnalysisHTML($appr_id);
1669 
1670  $tpl->setContent($html);
1671  } else { // must be all survey competences
1672  $pskills_gui = new ilPersonalSkillsGUI();
1673  #23743
1674  if ($survey->getMode() != ilObjSurvey::MODE_SELF_EVAL) {
1675  $pskills_gui->setGapAnalysisActualStatusModePerObject($survey->getId(), $lng->txt("skmg_eval_type_1"));
1676  }
1677  if ($survey->getFinishedIdForAppraiseeIdAndRaterId($appr_id, $appr_id) > 0) {
1678  $sskill = new ilSurveySkill($survey);
1679  $self_levels = array();
1680  foreach ($sskill->determineSkillLevelsForAppraisee($appr_id, true) as $sl) {
1681  $self_levels[$sl["base_skill_id"]][$sl["tref_id"]] = $sl["new_level_id"];
1682  }
1683  $pskills_gui->setGapAnalysisSelfEvalLevels($self_levels);
1684  }
1685  $sk = array();
1686  foreach ($skills as $skill) {
1687  $sk[] = array(
1688  "base_skill_id" => (int) $skill["base_skill"],
1689  "tref_id" => (int) $skill["tref_id"]
1690  );
1691  }
1692  $html = $pskills_gui->getGapAnalysisHTML($appr_id, $sk);
1693 
1694  $tpl->setContent($html);
1695  }
1696  }
1697 
1701  protected function hasResultsAccess()
1702  {
1703  return $this->access->checkRbacOrPositionPermissionAccess('read_results', 'access_results', $this->object->getRefId());
1704  }
1705 
1706  public function evaluationpdf()
1707  {
1708  $this->evaluation(0, true);
1709  }
1710 
1711  public function evaluationdetailspdf()
1712  {
1713  $this->evaluation(1, true);
1714  }
1715 
1716  public function downloadChart()
1717  {
1718  $qid = (int) $_GET["qid"];
1719  if (!$qid) {
1720  return;
1721  }
1722 
1723  $this->renderChartOnly();
1724  }
1725 
1726  public function renderChartOnly()
1727  {
1728  global $tpl;
1729 
1730  $qid = (int) $_GET["qid"];
1731  if (!$qid) {
1732  return;
1733  }
1734 
1735  $finished_ids = null;
1736  if ($this->object->get360Mode()) {
1737  $appr_id = $this->getAppraiseeId();
1738  $finished_ids = $this->object->getFinishedIdsForAppraiseeId($appr_id);
1739  if (!sizeof($finished_ids)) {
1740  $finished_ids = array(-1);
1741  }
1742  }
1743 
1744  // parse answer data in evaluation results
1745  foreach ($this->object->getSurveyQuestions() as $qdata) {
1746  if ($qid == $qdata["question_id"]) {
1747  $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($qdata["question_id"], $finished_ids);
1748  $q_res = $q_eval->getResults();
1749 
1750  $chart = $q_eval->getChart($q_res);
1751  if ($chart) {
1752  $dtmpl = new ilTemplate("tpl.il_svy_svy_results_details_single.html", true, true, "Modules/Survey");
1753 
1754  if (is_array($chart)) {
1755  // legend
1756  if (is_array($chart[1])) {
1757  foreach ($chart[1] as $legend_item) {
1758  $dtmpl->setCurrentBlock("legend_bl");
1759  $dtmpl->setVariable("LEGEND_CAPTION", $legend_item[0]);
1760  $dtmpl->setVariable("LEGEND_COLOR", $legend_item[1]);
1761  $dtmpl->parseCurrentBlock();
1762  }
1763  }
1764 
1765  $chart = $chart[0];
1766  }
1767  $dtmpl->setVariable("CHART", $chart);
1768  }
1769  }
1770  }
1771 
1772  // "print view"
1773  $this->tpl->setContent($dtmpl->get());
1774 
1775  $html = $this->tpl->printToString();
1776  $this->generateAndSendPDF($html, $this->object->getTitle() . " - " . SurveyQuestion::_getTitle($qid) . ".pdf");
1777  }
1778 
1785  public function generateAndSendPDF($html, $filename = "")
1786  {
1787  // :TODO: fixing css dummy parameters
1788  $html = preg_replace("/\?dummy\=[0-9]+/", "", $html);
1789  $html = preg_replace("/\?vers\=[0-9A-Za-z\-]+/", "", $html);
1790  $html = preg_replace("/\&version\=[0-9A-Za-z\-\._]+/", "", $html);
1791  $html = str_replace('.css$Id$', ".css", $html);
1792  $html = preg_replace("/src=\"\\.\\//ims", "src=\"" . ILIAS_HTTP_PATH . "/", $html);
1793  $html = preg_replace("/href=\"\\.\\//ims", "href=\"" . ILIAS_HTTP_PATH . "/", $html);
1794 
1795  //echo $html; exit;
1796 
1797  if ($filename == "") {
1798  $filename = $this->object->getTitle() . ".pdf";
1799  }
1800  $filename = str_replace('/', '_', $filename);
1801  $pdf_factory = new ilHtmlToPdfTransformerFactory();
1802  $pdf_factory->deliverPDFFromHTMLString($html, $filename, ilHtmlToPdfTransformerFactory::PDF_OUTPUT_DOWNLOAD, "Survey", "Results");
1803  }
1804 
1808  public function sumscore()
1809  {
1810  $ilToolbar = $this->toolbar;
1811 
1812  if (!$this->hasResultsAccess() &&
1813  $this->object->getMode() != ilObjSurvey::MODE_SELF_EVAL) {
1814  ilUtil::sendFailure($this->lng->txt("no_permission"), true);
1815  $this->ctrl->redirectByClass("ilObjSurveyGUI", "infoScreen");
1816  }
1817 
1818  ilUtil::sendInfo($this->lng->txt("svy_max_sum_score") . ": " . $this->object->getMaxSumScore());
1819 
1820  $ilToolbar->setFormAction($this->ctrl->getFormAction($this, "evaluationuser"));
1821 
1822  $modal_id = "svy_ev_exp";
1823  $modal = $this->buildExportModal($modal_id, "exportevaluationuser");
1824 
1825  $button = ilLinkButton::getInstance();
1826  $button->setCaption("print");
1827  $button->setOnClick("window.print(); return false;");
1828  $button->setOmitPreventDoubleSubmission(true);
1829  $ilToolbar->addButtonInstance($button);
1830 
1831  $finished_ids = null;
1832 
1833  $sum_scores = $this->getSumScores($finished_ids);
1834  $table_gui = new ilSumScoreTableGUI($this, 'sumscore', $this->object->hasAnonymizedResults());
1835  $table_gui->setSumScores($sum_scores);
1836  $this->tpl->setContent($table_gui->getHTML() . $modal);
1837  }
1838 
1839  protected function getSumScores(array $a_finished_ids = null) : array
1840  {
1841  $sum_scores = [];
1842  foreach ($this->filterSurveyParticipantsByAccess($a_finished_ids) as $p) {
1843  $sum_scores[$p["active_id"]] = [
1844  "username" => $p["sortname"],
1845  "score" => 0
1846  ];
1847  }
1848 
1849  foreach ($this->object->getSurveyQuestions() as $qdata) {
1850  $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($qdata["question_id"], $a_finished_ids);
1851  foreach ($q_eval->getSumScores() as $finished_id => $sum_score) {
1852  if ($sum_score === null) {
1853  $sum_scores[$finished_id]["score"] = null;
1854  }
1855  if ($sum_scores[$finished_id]["score"] !== null) {
1856  $sum_scores[$finished_id]["score"] += (int) $sum_score;
1857  }
1858  }
1859  }
1860  return $sum_scores;
1861  }
1862 }
static _getIcon( $a_obj_id="", $a_size="big", $a_type="", $a_offline=false)
Get icon for repository item.
setSumScores($scores)
Set sum scores.
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
if(isset($_FILES['img_file']) &&is_array($_FILES['img_file'])) $panel
Definition: imgupload.php:138
$_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)
getSumScores(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
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.
const RESULTS_SELF_EVAL_OWN
static _lookupObjId($a_id)
global $DIC
Definition: goto.php:24
competenceEval()
Competence Evaluation.
generateAndSendPDF($html, $filename="")
$format
Definition: metadata.php:218
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 getInstance()
Get instance.
setColors($a_coords, $a_background, $a_font=null)
Set cell(s) colors.
$ret
Definition: parser.php:6
__construct($a_object)
ilSurveyEvaluationGUI constructor
static getLogger($a_component_id)
Get component logger.
$url
$ilUser
Definition: imgupload.php:18
Survey evaluation graphical output.
evaluationdetails()
Show the detailed evaluation.
Accordion user interface class.
sumscore()
Show sum score table.
$cols
Definition: xhr_table.php:11
const RESULTS_SELF_EVAL_ALL
$_POST["username"]
const TYPE_SPSS
determineAppraiseeId()
Determine appraisee id.
getTextAnswers($a_results)
Get text answers.