ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilTestServiceGUI.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
5 include_once 'Modules/Test/classes/class.ilTestService.php';
6 
22 {
26  public $object = null;
27 
31  public $service = null;
32 
33  var $lng;
34  var $tpl;
35 
39  var $ctrl;
40 
41  var $ilias;
42  var $tree;
43  var $ref_id;
44 
50  protected $testSessionFactory = null;
51 
57  protected $testSequenceFactory = null;
58 
65  function ilTestServiceGUI(ilObjTest $a_object)
66  {
67  global $lng, $tpl, $ilCtrl, $ilias, $tree, $ilDB, $ilPluginAdmin;
68 
69  $this->lng =& $lng;
70  $this->tpl =& $tpl;
71  $this->ctrl =& $ilCtrl;
72  $this->ilias =& $ilias;
73  $this->object =& $a_object;
74  $this->tree =& $tree;
75  $this->ref_id = $a_object->ref_id;
76 
77  $this->service = new ilTestService($a_object);
78 
79  require_once 'Modules/Test/classes/class.ilTestSessionFactory.php';
80  $this->testSessionFactory = new ilTestSessionFactory($this->object);
81 
82  require_once 'Modules/Test/classes/class.ilTestSequenceFactory.php';
83  $this->testSequenceFactory = new ilTestSequenceFactory($ilDB, $this->lng, $ilPluginAdmin, $this->object);
84  }
85 
89  function &executeCommand()
90  {
91  $cmd = $this->ctrl->getCmd();
92  $next_class = $this->ctrl->getNextClass($this);
93 
94  $cmd = $this->getCommand($cmd);
95  switch($next_class)
96  {
97  default:
98  $ret =& $this->$cmd();
99  break;
100  }
101  return $ret;
102  }
103 
109  function getCommand($cmd)
110  {
111  return $cmd;
112  }
113 
122  public function getPassOverview($active_id, $targetclass = "", $targetcommand = "", $short = FALSE, $hide_details = FALSE)
123  {
124  require_once 'Services/UIComponent/AdvancedSelectionList/classes/class.ilAdvancedSelectionListGUI.php';
125  require_once 'Modules/Test/classes/tables/class.ilTestPassOverviewTableGUI.php';
126 
127  $table = new ilTestPassOverviewTableGUI(
128  $this,
129  '',
131  (isset($_GET['pdf']) && $_GET['pdf'] == 1)
132  );
133  $data = array();
134 
135  $counted_pass = $this->object->_getResultPass($active_id);
136  $reached_pass = $this->object->_getPass($active_id);
137 
138  require_once 'Modules/Test/classes/class.ilTestPassesSelector.php';
139  $testPassesSelector = new ilTestPassesSelector($GLOBALS['ilDB'], $this->object);
140  $testPassesSelector->setActiveId($active_id);
141  $lastFinishedPass = $this->testSessionFactory->getSession($active_id)->getLastFinishedPass();
142  $testPassesSelector->setLastFinishedPass($lastFinishedPass);
143 
144  foreach($testPassesSelector->getReportablePasses() as $pass)
145  {
146  $row = array();
147 
148  if(!$short)
149  {
150  $result_array =& $this->object->getTestResult($active_id, $pass);
151  if(!$result_array['pass']['total_max_points'])
152  {
153  $percentage = 0;
154  }
155  else
156  {
157  $percentage = ($result_array['pass']['total_reached_points'] / $result_array['pass']['total_max_points']) * 100;
158  }
159  $total_max = $result_array['pass']['total_max_points'];
160  $total_reached = $result_array['pass']['total_reached_points'];
161  $total_requested_hints = $result_array['pass']['total_requested_hints'];
162  }
163  if(!$hide_details)
164  {
165  if(strlen($targetclass) && strlen($targetcommand))
166  {
167  $this->ctrl->setParameterByClass($targetclass, 'active_id', $active_id);
168  $this->ctrl->setParameterByClass($targetclass, 'pass', $pass);
169 
170  $aslgui = new ilAdvancedSelectionListGUI();
171  $aslgui->setListTitle($this->lng->txt('actions'));
172  $aslgui->setId($pass);
173  $aslgui->addItem(
174  $this->lng->txt('tst_pass_details'),
175  'tst_pass_details',
176  $this->ctrl->getLinkTargetByClass($targetclass, $targetcommand)
177  );
178  if($this->object->isPassDeletionAllowed() && $pass != $counted_pass)
179  {
180  $aslgui->addItem(
181  $this->lng->txt('delete'),
182  'tst_pass_delete',
183  $this->ctrl->getLinkTargetByClass($targetclass, 'confirmDeletePass')
184  );
185  }
186  $row['pass_details'] = $aslgui->getHTML();
187  }
188  }
189 
190  if(!$short)
191  {
192  if(($pass == $counted_pass))
193  {
194  $row['scored'] = '&otimes;';
195  }
196  else
197  {
198  $row['scored'] = '';
199  }
200  }
201 
202  $row['pass'] = $pass + 1;
203  $row['date'] = $this->object->getPassFinishDate($active_id, $pass);
204  if(!$short)
205  {
206  $row['answered'] = $result_array['pass']['num_workedthrough'] . ' ' . strtolower($this->lng->txt('of')) . ' ' . (count($result_array) - 2);
207  if($this->object->isOfferingQuestionHintsEnabled())
208  {
209  $row['hints'] = $total_requested_hints;
210  }
211  $row['reached'] = $total_reached . ' ' . strtolower($this->lng->txt('of')) . ' ' . $total_max;
212  $row['percentage'] = $percentage;
213  }
214 
215  $data[] = $row;
216  }
217 
218  $table->setData($data);
219  return $table->getHTML();
220  }
221 
229  function getFinalStatement($active_id)
230  {
231  $test_data_array = $this->object->getResultsForActiveId($active_id);
232 
233  $obligationsAnswered = $test_data_array['obligations_answered'];
234 
235  if (!$test_data_array["max_points"])
236  {
237  $percentage = 0;
238  }
239  else
240  {
241  $percentage = ($test_data_array["reached_points"]/$test_data_array["max_points"])*100;
242  }
243  $total_max = $test_data_array["max_points"];
244  $total_reached = $test_data_array["reached_points"];
245  $result_percentage = $percentage;
246  $result_total_reached = $total_reached;
247  $result_total_max = $total_max;
248 
249  $mark = "";
250  $markects = "";
251  $mark_obj = $this->object->mark_schema->getMatchingMark($result_percentage);
252  if ($mark_obj)
253  {
254  require_once './Modules/Test/classes/class.ilTestFinalMarkLangVarBuilder.php';
255  $langVarBuilder = new ilTestFinalMarkLangVarBuilder(
256  $mark_obj->getPassed(), $obligationsAnswered, $this->object->areObligationsEnabled()
257  );
258 
259  $mark = $this->lng->txt( $langVarBuilder->build() );
260 
261  $mark = str_replace("[mark]", $mark_obj->getOfficialName(), $mark);
262  $mark = str_replace("[markshort]", $mark_obj->getShortName(), $mark);
263  $mark = str_replace("[percentage]", sprintf("%.2f", $result_percentage), $mark);
264  $mark = str_replace("[reached]", $result_total_reached, $mark);
265  $mark = str_replace("[max]", $result_total_max, $mark);
266  }
267  if ($this->object->ects_output)
268  {
269  $passed_array =& $this->object->getTotalPointsPassedArray();
270  $ects_mark = $this->object->getECTSGrade($passed_array, $result_total_reached, $result_total_max);
271  $markects = $this->lng->txt("mark_tst_ects");
272  $markects = str_replace("[markects]", $this->lng->txt("ects_grade_". strtolower($ects_mark)), $markects);
273  }
274  return array("mark" => $mark, "markects" => $markects);
275  }
276 
287  function getPassListOfAnswers(&$result_array, $active_id, $pass, $show_solutions = FALSE, $only_answered_questions = FALSE, $show_question_only = FALSE, $show_reached_points = FALSE)
288  {
289  $maintemplate = new ilTemplate("tpl.il_as_tst_list_of_answers.html", TRUE, TRUE, "Modules/Test");
290 
291  $counter = 1;
292  // output of questions with solutions
293  foreach ($result_array as $question_data)
294  {
295  if (($question_data["workedthrough"] == 1) || ($only_answered_questions == FALSE))
296  {
297  $template = new ilTemplate("tpl.il_as_qpl_question_printview.html", TRUE, TRUE, "Modules/TestQuestionPool");
298  $question = $question_data["qid"];
299  if (is_numeric($question))
300  {
301  $maintemplate->setCurrentBlock("printview_question");
302  $question_gui = $this->object->createQuestionGUI("", $question);
303  if (is_object($question_gui))
304  {
305  if ($show_reached_points)
306  {
307  $template->setCurrentBlock("result_points");
308  $template->setVariable("RESULT_POINTS", $this->lng->txt("tst_reached_points") . ": " . $question_gui->object->getReachedPoints($active_id, $pass) . " " . $this->lng->txt("of") . " " . $question_gui->object->getMaximumPoints());
309  $template->parseCurrentBlock();
310  }
311  $template->setVariable("COUNTER_QUESTION", $counter.". ");
312  $template->setVariable("TXT_QUESTION_ID", $this->lng->txt('question_id_short'));
313  $template->setVariable("QUESTION_ID", $question_gui->object->getId());
314  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitle()));
315 
316  $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? TRUE : FALSE;
317 
318  if($show_solutions)
319  {
320  $compare_template = new ilTemplate('tpl.il_as_tst_answers_compare.html', TRUE, TRUE, 'Modules/Test');
321  $compare_template->setVariable("HEADER_PARTICIPANT", $this->lng->txt('tst_header_participant'));
322  $compare_template->setVariable("HEADER_SOLUTION", $this->lng->txt('tst_header_solution'));
323  $result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_solutions, FALSE, $show_question_only, $this->object->getShowSolutionFeedback());
324  $best_output = $question_gui->getSolutionOutput($active_id, $pass, FALSE, FALSE, $show_question_only, FALSE, TRUE);
325 
326  $compare_template->setVariable('PARTICIPANT', $result_output);
327  $compare_template->setVariable('SOLUTION', $best_output);
328  $template->setVariable('SOLUTION_OUTPUT', $compare_template->get());
329  }
330  else
331  {
332  $result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_solutions, FALSE, $show_question_only, $this->object->getShowSolutionFeedback());
333  $template->setVariable('SOLUTION_OUTPUT', $result_output);
334  }
335 
336  $maintemplate->setCurrentBlock("printview_question");
337  $maintemplate->setVariable("QUESTION_PRINTVIEW", $template->get());
338  $maintemplate->parseCurrentBlock();
339  $counter ++;
340  }
341  }
342  }
343  }
344  $maintemplate->setVariable("RESULTS_OVERVIEW", sprintf($this->lng->txt("tst_eval_results_by_pass"), $pass + 1));
345  return $maintemplate->get();
346  }
347 
360  function getPassListOfAnswersWithScoring(&$result_array, $active_id, $pass, $show_solutions = FALSE)
361  {
362  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
363 
364  $maintemplate = new ilTemplate("tpl.il_as_tst_list_of_answers.html", TRUE, TRUE, "Modules/Test");
365 
366  include_once "./Modules/Test/classes/class.ilObjAssessmentFolder.php";
368 
369  $counter = 1;
370  // output of questions with solutions
371  foreach ($result_array as $question_data)
372  {
373  $question = $question_data["qid"];
374  if (is_numeric($question))
375  {
376  $question_gui = $this->object->createQuestionGUI("", $question);
377  if (in_array($question_gui->object->getQuestionTypeID(), $scoring))
378  {
379  $template = new ilTemplate("tpl.il_as_qpl_question_printview.html", TRUE, TRUE, "Modules/TestQuestionPool");
380  $scoretemplate = new ilTemplate("tpl.il_as_tst_manual_scoring_points.html", TRUE, TRUE, "Modules/Test");
381  #mbecker: No such block. $this->tpl->setCurrentBlock("printview_question");
382  $template->setVariable("COUNTER_QUESTION", $counter.". ");
383  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitle()));
384  $points = $question_gui->object->getMaximumPoints();
385  if ($points == 1)
386  {
387  $template->setVariable("QUESTION_POINTS", $points . " " . $this->lng->txt("point"));
388  }
389  else
390  {
391  $template->setVariable("QUESTION_POINTS", $points . " " . $this->lng->txt("points"));
392  }
393 
394  $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? TRUE : FALSE;
395  $result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_solutions, FALSE, $show_question_only, $this->object->getShowSolutionFeedback(), FALSE, TRUE);
396 
397  $solout = $question_gui->object->getSuggestedSolutionOutput();
398  if (strlen($solout))
399  {
400  $scoretemplate->setCurrentBlock("suggested_solution");
401  $scoretemplate->setVariable("TEXT_SUGGESTED_SOLUTION", $this->lng->txt("solution_hint"));
402  $scoretemplate->setVariable("VALUE_SUGGESTED_SOLUTION", $solout);
403  $scoretemplate->parseCurrentBlock();
404  }
405 
406  $scoretemplate->setCurrentBlock("feedback");
407  $scoretemplate->setVariable("FEEDBACK_NAME_INPUT", $question);
408  $feedback = $this->object->getManualFeedback($active_id, $question, $pass);
409  $scoretemplate->setVariable("VALUE_FEEDBACK", ilUtil::prepareFormOutput($this->object->prepareTextareaOutput($feedback, TRUE)));
410  $scoretemplate->setVariable("TEXT_MANUAL_FEEDBACK", $this->lng->txt("set_manual_feedback"));
411  $scoretemplate->parseCurrentBlock();
412 
413  $scoretemplate->setVariable("NAME_INPUT", $question);
414  $this->ctrl->setParameter($this, "active_id", $active_id);
415  $this->ctrl->setParameter($this, "pass", $pass);
416  $scoretemplate->setVariable("FORMACTION", $this->ctrl->getFormAction($this, "manscoring"));
417  $scoretemplate->setVariable("LABEL_INPUT", $this->lng->txt("tst_change_points_for_question"));
418  $scoretemplate->setVariable("VALUE_INPUT", " value=\"" . assQuestion::_getReachedPoints($active_id, $question_data["qid"], $pass) . "\"");
419  $scoretemplate->setVariable("VALUE_SAVE", $this->lng->txt("save"));
420 
421  $template->setVariable("SOLUTION_OUTPUT", $result_output);
422  $maintemplate->setCurrentBlock("printview_question");
423  $maintemplate->setVariable("QUESTION_PRINTVIEW", $template->get());
424  $maintemplate->setVariable("QUESTION_SCORING", $scoretemplate->get());
425  $maintemplate->parseCurrentBlock();
426  }
427  $counter ++;
428  }
429  }
430  if ($counter == 1)
431  {
432  // no scorable questions found
433  $maintemplate->setVariable("NO_QUESTIONS_FOUND", $this->lng->txt("manscoring_questions_not_found"));
434  }
435  $maintemplate->setVariable("RESULTS_OVERVIEW", sprintf($this->lng->txt("manscoring_results_pass"), $pass+1));
436 
437  include_once "./Services/YUI/classes/class.ilYuiUtil.php";
439 
440  return $maintemplate->get();
441  }
442 
443 
459  function getPassDetailsOverview($result_array, $active_id, $pass, $targetclass = "", $targetcommandsort = "", $targetcommanddetails = "", $standard_header = TRUE)
460  {
461  global $ilUser;
462 
463  $testresults = $result_array["pass"];
464  unset($result_array["test"]);
465  $user_id = $this->object->_getUserIdFromActiveId($active_id);
466 
467  $sort = ($_GET["sort"]) ? ($_GET["sort"]) : "nr";
468  $sortorder = ($_GET["sortorder"]) ? ($_GET["sortorder"]) : "asc";
469 
470  if (!$standard_header)
471  {
472  // change sortorder of result array
473  usort($result_array, "sortResults");
474  }
475  $color_class = array("tblrow1top", "tblrow2top");
476  $counter = 0;
477  $template = new ilTemplate("tpl.il_as_tst_pass_details_overview.html", TRUE, TRUE, "Modules/Test");
478  $this->ctrl->setParameterByClass($targetclass, "pass", "$pass");
479 
480  if (!$testresults["total_max_points"])
481  {
482  $percentage = 0;
483  }
484  else
485  {
486  $percentage = ($testresults["total_reached_points"]/$testresults["total_max_points"])*100;
487  }
488  $total_max = $testresults["total_max_points"];
489  $total_reached = $testresults["total_reached_points"];
490  $totalRequestedHints = $testresults["total_requested_hints"];
491 
492  $img_title_percent = "";
493  $img_title_nr = "";
494  $hasSuggestedSolutions = FALSE;
495  if ($this->object->getShowSolutionSuggested())
496  {
497  foreach ($result_array as $key => $value)
498  {
499  if (strlen($value["solution"]))
500  {
501  $hasSuggestedSolutions = TRUE;
502  }
503  }
504  }
505  foreach ($result_array as $key => $value)
506  {
507  if (preg_match("/\d+/", $key))
508  {
509  if (strlen($targetclass) && strlen($targetcommanddetails))
510  {
511  $template->setCurrentBlock("linked_title");
512  $template->setVariable("COLOR_CLASS", $color_class[$counter % 2]);
513  $template->setVariable("VALUE_QUESTION_TITLE", $value["title"]);
514  $this->ctrl->setParameterByClass($targetclass, "evaluation", $value["qid"]);
515  $this->ctrl->setParameterByClass($targetclass, "active_id", $active_id);
516  $template->setVariable("URL_QUESTION_TITLE", $this->ctrl->getLinkTargetByClass($targetclass, $targetcommanddetails));
517  $template->parseCurrentBlock();
518  }
519  else
520  {
521  $template->setCurrentBlock("plain_title");
522  $template->setVariable("VALUE_QUESTION_TITLE", $value["title"]);
523  $template->setVariable("COLOR_CLASS", $color_class[$counter % 2]);
524  $template->parseCurrentBlock();
525  }
526  if ($hasSuggestedSolutions)
527  {
528  $template->setCurrentBlock("question_suggested_solution");
529  $template->setVariable("COLOR_CLASS", $color_class[$counter % 2]);
530  $template->setVariable("SOLUTION_HINT", $this->object->prepareTextareaOutput($value["solution"], true));
531  $template->parseCurrentBlock();
532  }
533  $template->setCurrentBlock("question");
534  $template->setVariable("COLOR_CLASS", $color_class[$counter % 2]);
535  $template->setVariable("VALUE_QUESTION_ID", $value["qid"]);
536  $template->setVariable("VALUE_QUESTION_COUNTER", $value["nr"]);
537  $template->setVariable("VALUE_MAX_POINTS", $value["max"]);
538  $template->setVariable("VALUE_REACHED_POINTS", $value["reached"]);
539  if( $this->object->isOfferingQuestionHintsEnabled() )
540  {
541  $template->setVariable("VALUE_HINT_COUNT", $value["requested_hints"]);
542  }
543  $template->setVariable("VALUE_PERCENT_SOLVED", $value["percent"]);
544  $template->parseCurrentBlock();
545  $counter++;
546  }
547  }
548 
549  if ($hasSuggestedSolutions)
550  {
551  $template->touchBlock("footer_suggested_solution");
552  }
553  $template->setCurrentBlock("footer");
554  $template->setVariable("VALUE_QUESTION_COUNTER", "<strong>" . $this->lng->txt("total") . "</strong>");
555  $template->setVariable("VALUE_QUESTION_ID", "");
556  $template->setVariable("VALUE_QUESTION_TITLE", "");
557  $template->setVariable("VALUE_MAX_POINTS", "<strong>$total_max</strong>");
558  $template->setVariable("VALUE_REACHED_POINTS", "<strong>$total_reached</strong>");
559  if( $this->object->isOfferingQuestionHintsEnabled() )
560  {
561  $template->setVariable("VALUE_TOTAL_HINT_COUNT", "<strong>$totalRequestedHints</strong>");
562  }
563  $template->setVariable("VALUE_PERCENT_SOLVED", "<strong>" . sprintf("%2.2f", $percentage) . " %" . "</strong>");
564  $template->parseCurrentBlock();
565 
566  if ($standard_header)
567  {
568  if ($hasSuggestedSolutions)
569  {
570  $template->setCurrentBlock("standard_header_suggested_solution");
571  $template->setVariable("SOLUTION_HINT_HEADER", $this->lng->txt("solution_hint"));
572  $template->parseCurrentBlock();
573  }
574  $template->setCurrentBlock("standard_header");
575  $template->setVariable("QUESTION_COUNTER", $this->lng->txt("tst_question_no"));
576  $template->setVariable("PERCENT_SOLVED", $this->lng->txt("tst_percent_solved"));
577  $template->setVariable("QUESTION_ID", $this->lng->txt("question_id"));
578  $template->setVariable("QUESTION_TITLE", $this->lng->txt("tst_question_title"));
579  $template->setVariable("MAX_POINTS", $this->lng->txt("tst_maximum_points"));
580  $template->setVariable("REACHED_POINTS", $this->lng->txt("tst_reached_points"));
581  if( $this->object->isOfferingQuestionHintsEnabled() )
582  {
583  $template->setVariable("HINT_COUNT", $this->lng->txt("tst_question_hints_requested_hint_count_header"));
584  }
585  $template->parseCurrentBlock();
586  }
587  else
588  {
589  if ($hasSuggestedSolutions)
590  {
591  $template->setCurrentBlock("linked_header_suggested_solution");
592  if (strcmp($sort, "solution") == 0)
593  {
594  $this->ctrl->setParameterByClass($targetclass, "sortorder", !strcmp($sortorder, "asc") ? "desc" : "asc");
595  }
596  else
597  {
598  $this->ctrl->setParameterByClass($targetclass, "sortorder", "asc");
599  }
600  $this->ctrl->setParameterByClass($targetclass, "sort", "solution");
601  $template->setVariable("URL_SOLUTION_HINT_HEADER", $this->ctrl->getLinkTargetByClass($targetclass, $targetcommandsort));
602  $template->setVariable("SOLUTION_HINT_HEADER", $this->lng->txt("solution_hint"));
603  if (strcmp($sort, "solution") == 0)
604  {
605  $image = new ilTemplate("tpl.image.html", TRUE, TRUE, "Modules/Test");
606  $image->setVariable("IMAGE_SOURCE", ilUtil::getImagePath($sortorder . "_order.png"));
607  $image->setVariable("IMAGE_ALT", $this->lng->txt("change_sort_direction"));
608  $image->setVariable("IMAGE_TITLE", $this->lng->txt("change_sort_direction"));
609  $template->setVariable("IMAGE_SOLUTION_HINT_HEADER", $image->get());
610  }
611  $template->parseCurrentBlock();
612  }
613  $template->setCurrentBlock("linked_header");
614  $this->ctrl->setParameterByClass($targetclass, "sort", "nr");
615  if (strcmp($sort, "nr") == 0)
616  {
617  $this->ctrl->setParameterByClass($targetclass, "sortorder", !strcmp($sortorder, "asc") ? "desc" : "asc");
618  }
619  else
620  {
621  $this->ctrl->setParameterByClass($targetclass, "sortorder", "asc");
622  }
623  $template->setVariable("URL_QUESTION_COUNTER", $this->ctrl->getLinkTargetByClass($targetclass, $targetcommandsort));
624  $template->setVariable("QUESTION_COUNTER", $this->lng->txt("tst_question_no"));
625  if (strcmp($sort, "nr") == 0)
626  {
627  $image = new ilTemplate("tpl.image.html", TRUE, TRUE, "Modules/Test");
628  $image->setVariable("IMAGE_SOURCE", ilUtil::getImagePath($sortorder . "_order.png"));
629  $image->setVariable("IMAGE_ALT", $this->lng->txt("change_sort_direction"));
630  $image->setVariable("IMAGE_TITLE", $this->lng->txt("change_sort_direction"));
631  $template->setVariable("IMAGE_QUESTION_COUNTER", $image->get());
632  }
633  $this->ctrl->setParameterByClass($targetclass, "sort", "percent");
634  if (strcmp($sort, "percent") == 0)
635  {
636  $this->ctrl->setParameterByClass($targetclass, "sortorder", !strcmp($sortorder, "asc") ? "desc" : "asc");
637  }
638  else
639  {
640  $this->ctrl->setParameterByClass($targetclass, "sortorder", "asc");
641  }
642  $template->setVariable("URL_PERCENT_SOLVED", $this->ctrl->getLinkTargetByClass($targetclass, $targetcommandsort));
643  $template->setVariable("PERCENT_SOLVED", $this->lng->txt("tst_percent_solved"));
644  if (strcmp($sort, "percent") == 0)
645  {
646  $image = new ilTemplate("tpl.image.html", TRUE, TRUE, "Modules/Test");
647  $image->setVariable("IMAGE_SOURCE", ilUtil::getImagePath($sortorder . "_order.png"));
648  $image->setVariable("IMAGE_ALT", $this->lng->txt("change_sort_direction"));
649  $image->setVariable("IMAGE_TITLE", $this->lng->txt("change_sort_direction"));
650  $template->setVariable("IMAGE_PERCENT_SOLVED", $image->get());
651  }
652  $this->ctrl->setParameterByClass($targetclass, "sort", "title");
653  if (strcmp($sort, "title") == 0)
654  {
655  $this->ctrl->setParameterByClass($targetclass, "sortorder", !strcmp($sortorder, "asc") ? "desc" : "asc");
656  }
657  else
658  {
659  $this->ctrl->setParameterByClass($targetclass, "sortorder", "asc");
660  }
661  $template->setVariable("URL_QUESTION_TITLE", $this->ctrl->getLinkTargetByClass($targetclass, $targetcommandsort));
662  $template->setVariable("QUESTION_TITLE", $this->lng->txt("tst_question_title"));
663  if (strcmp($sort, "title") == 0)
664  {
665  $image = new ilTemplate("tpl.image.html", TRUE, TRUE, "Modules/Test");
666  $image->setVariable("IMAGE_SOURCE", ilUtil::getImagePath($sortorder . "_order.png"));
667  $image->setVariable("IMAGE_ALT", $this->lng->txt("change_sort_direction"));
668  $image->setVariable("IMAGE_TITLE", $this->lng->txt("change_sort_direction"));
669  $template->setVariable("IMAGE_QUESTION_TITLE", $image->get());
670  }
671  $this->ctrl->setParameterByClass($targetclass, "sort", "max");
672  if (strcmp($sort, "max") == 0)
673  {
674  $this->ctrl->setParameterByClass($targetclass, "sortorder", strcmp($sortorder, "asc") ? "desc" : "asc");
675  }
676  else
677  {
678  $this->ctrl->setParameterByClass($targetclass, "sortorder", "asc");
679  }
680  $template->setVariable("URL_MAX_POINTS", $this->ctrl->getLinkTargetByClass($targetclass, $targetcommandsort));
681  $template->setVariable("MAX_POINTS", $this->lng->txt("tst_maximum_points"));
682  if (strcmp($sort, "max") == 0)
683  {
684  $image = new ilTemplate("tpl.image.html", TRUE, TRUE, "Modules/Test");
685  $image->setVariable("IMAGE_SOURCE", ilUtil::getImagePath($sortorder . "_order.png"));
686  $image->setVariable("IMAGE_ALT", $this->lng->txt("change_sort_direction"));
687  $image->setVariable("IMAGE_TITLE", $this->lng->txt("change_sort_direction"));
688  $template->setVariable("IMAGE_MAX_POINTS", $image->get());
689  }
690  $this->ctrl->setParameterByClass($targetclass, "sort", "reached");
691  if (strcmp($sort, "reached") == 0)
692  {
693  $this->ctrl->setParameterByClass($targetclass, "sortorder", !strcmp($sortorder, "asc") ? "desc" : "asc");
694  }
695  else
696  {
697  $this->ctrl->setParameterByClass($targetclass, "sortorder", "asc");
698  }
699  $template->setVariable("URL_REACHED_POINTS", $this->ctrl->getLinkTargetByClass($targetclass, $targetcommandsort));
700  $template->setVariable("REACHED_POINTS", $this->lng->txt("tst_reached_points"));
701  if (strcmp($sort, "reached") == 0)
702  {
703  $image = new ilTemplate("tpl.image.html", TRUE, TRUE, "Modules/Test");
704  $image->setVariable("IMAGE_SOURCE", ilUtil::getImagePath($sortorder . "_order.png"));
705  $image->setVariable("IMAGE_ALT", $this->lng->txt("change_sort_direction"));
706  $image->setVariable("IMAGE_TITLE", $this->lng->txt("change_sort_direction"));
707  $template->setVariable("IMAGE_REACHED_POINTS", $image->get());
708  }
709  $template->parseCurrentBlock();
710  }
711 
712  return $template->get();
713  }
714 
722  {
723  if ($this->object->getShowSolutionSignature() && !$this->object->getAnonymity())
724  {
725  $template = new ilTemplate("tpl.il_as_tst_results_userdata_signature.html", TRUE, TRUE, "Modules/Test");
726  $template->setVariable("TXT_DATE", $this->lng->txt("date"));
729  $template->setVariable("VALUE_DATE", ilDatePresentation::formatDate(new ilDate(time(), IL_CAL_UNIX)));
731  $template->setVariable("TXT_SIGNATURE", $this->lng->txt("tst_signature"));
732  $template->setVariable("IMG_SPACER", ilUtil::getImagePath("spacer.png"));
733  return $template->get();
734  }
735  else
736  {
737  return "";
738  }
739  }
740 
750  function getResultsUserdata($testSession, $active_id, $overwrite_anonymity = FALSE)
751  {
752  if(!is_object($testSession)) throw new TestException();
753  $template = new ilTemplate("tpl.il_as_tst_results_userdata.html", TRUE, TRUE, "Modules/Test");
754  include_once './Services/User/classes/class.ilObjUser.php';
755  $user_id = $this->object->_getUserIdFromActiveId($active_id);
756  if (strlen(ilObjUser::_lookupLogin($user_id)) > 0)
757  {
758  $user = new ilObjUser($user_id);
759  }
760  else
761  {
762  $user = new ilObjUser();
763  $user->setLastname($this->lng->txt("deleted_user"));
764  }
765  $t = $testSession->getSubmittedTimestamp();
766  if (!$t)
767  {
768  $t = $this->object->_getLastAccess($testSession->getActiveId());
769  }
770  $print_date = mktime(date("H"), date("i"), date("s"), date("m") , date("d"), date("Y"));
771 
772  $title_matric = "";
773  if (strlen($user->getMatriculation()) && (($this->object->getAnonymity() == FALSE) || ($overwrite_anonymity)))
774  {
775  $template->setCurrentBlock("user_matric");
776  $template->setVariable("TXT_USR_MATRIC", $this->lng->txt("matriculation"));
777  $template->parseCurrentBlock();
778  $template->setCurrentBlock("user_matric_value");
779  $template->setVariable("VALUE_USR_MATRIC", $user->getMatriculation());
780  $template->parseCurrentBlock();
781  $template->touchBlock("user_matric_separator");
782  $title_matric = " - " . $this->lng->txt("matriculation") . ": " . $user->getMatriculation();
783  }
784 
785  $invited_user = array_pop($this->object->getInvitedUsers($user_id));
786  if (strlen($invited_user["clientip"]))
787  {
788  $template->setCurrentBlock("user_clientip");
789  $template->setVariable("TXT_CLIENT_IP", $this->lng->txt("client_ip"));
790  $template->parseCurrentBlock();
791  $template->setCurrentBlock("user_clientip_value");
792  $template->setVariable("VALUE_CLIENT_IP", $invited_user["clientip"]);
793  $template->parseCurrentBlock();
794  $template->touchBlock("user_clientip_separator");
795  $title_client = " - " . $this->lng->txt("clientip") . ": " . $invited_user["clientip"];
796  }
797 
798  $template->setVariable("TXT_TEST_TITLE", $this->lng->txt("title"));
799  $template->setVariable("VALUE_TEST_TITLE", $this->object->getTitle());
800  $template->setVariable("TXT_USR_NAME", $this->lng->txt("name"));
801  $uname = $this->object->userLookupFullName($user_id, $overwrite_anonymity);
802  $template->setVariable("VALUE_USR_NAME", $uname);
803  $template->setVariable("TXT_TEST_DATE", $this->lng->txt("tst_tst_date"));
804  $template->setVariable("TXT_PRINT_DATE", $this->lng->txt("tst_print_date"));
807  $template->setVariable("VALUE_TEST_DATE", ilDatePresentation::formatDate(new ilDateTime(ilUtil::date_mysql2time($t), IL_CAL_UNIX)));
808  $template->setVariable("VALUE_PRINT_DATE", ilDatePresentation::formatDate(new ilDateTime($print_date, IL_CAL_UNIX)));
810 
811  // change the pagetitle
812  $pagetitle = ": " . $this->object->getTitle() . $title_matric . $title_client;
813  $this->tpl->setHeaderPageTitle($pagetitle);
814 
815  return $template->get();
816  }
817 
827  function getCorrectSolutionOutput($question_id, $active_id, $pass)
828  {
829  global $ilUser;
830 
831  $test_id = $this->object->getTestId();
832  $question_gui = $this->object->createQuestionGUI("", $question_id);
833 
834  $template = new ilTemplate("tpl.il_as_tst_correct_solution_output.html", TRUE, TRUE, "Modules/Test");
835  $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? TRUE : FALSE;
836  $result_output = $question_gui->getSolutionOutput($active_id, $pass, TRUE, FALSE, $show_question_only, $this->object->getShowSolutionFeedback(), FALSE, FALSE, TRUE);
837  $best_output = $question_gui->getSolutionOutput($active_id, $pass, FALSE, FALSE, $show_question_only, FALSE, TRUE, FALSE, FALSE);
838  if( $this->object->getShowSolutionFeedback() && $_GET['cmd'] != 'outCorrectSolution' )
839  {
840  $specificAnswerFeedback = $question_gui->getSpecificFeedbackOutput($active_id, $pass);
841  if( strlen($specificAnswerFeedback) )
842  {
843  $template->setCurrentBlock("outline_specific_feedback");
844  $template->setVariable("OUTLINE_SPECIFIC_FEEDBACK", $specificAnswerFeedback);
845  $template->parseCurrentBlock();
846  }
847  }
848  if ($this->object->isBestSolutionPrintedWithResult() && strlen($best_output))
849  {
850  $template->setCurrentBlock("best_solution");
851  $template->setVariable("TEXT_BEST_SOLUTION", $this->lng->txt("tst_best_solution_is"));
852  $template->setVariable("BEST_OUTPUT", $best_output);
853  $template->parseCurrentBlock();
854  }
855  $template->setVariable("TEXT_YOUR_SOLUTION", $this->lng->txt("tst_your_answer_was"));
856  $maxpoints = $question_gui->object->getMaximumPoints();
857  if ($maxpoints == 1)
858  {
859  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitle()) . " (" . $maxpoints . " " . $this->lng->txt("point") . ")");
860  }
861  else
862  {
863  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitle()) . " (" . $maxpoints . " " . $this->lng->txt("points") . ")");
864  }
865  $template->setVariable("SOLUTION_OUTPUT", $result_output);
866  $template->setVariable("RECEIVED_POINTS", sprintf($this->lng->txt("you_received_a_of_b_points"), $question_gui->object->getReachedPoints($active_id, $pass), $maxpoints));
867  $template->setVariable("FORMACTION", $this->ctrl->getFormAction($this));
868  $template->setVariable("BACKLINK_TEXT", "&lt;&lt; " . $this->lng->txt("back"));
869  return $template->get();
870  }
871 
884  function getResultsOfUserOutput($testSession, $active_id, $pass, $show_pass_details = TRUE, $show_answers = TRUE, $show_question_only = FALSE, $show_reached_points = FALSE)
885  {
886  global $ilias, $tpl;
887 
888  include_once("./Services/UICore/classes/class.ilTemplate.php");
889  $template = new ilTemplate("tpl.il_as_tst_results_participant.html", TRUE, TRUE, "Modules/Test");
890 
891  $user_id = $this->object->_getUserIdFromActiveId($active_id);
892  $uname = $this->object->userLookupFullName($user_id, TRUE);
893 
894  if (((array_key_exists("pass", $_GET)) && (strlen($_GET["pass"]) > 0)) || (!is_null($pass)))
895  {
896  if (is_null($pass)) $pass = $_GET["pass"];
897  }
898 
899  $statement = $this->getFinalStatement($active_id);
900 
901  $user_data = $this->getResultsUserdata($testSession, $active_id, TRUE);
902 
903  if (!is_null($pass))
904  {
905  $result_array =& $this->object->getTestResult($active_id, $pass);
906  $command_solution_details = "";
907  if ($show_pass_details)
908  {
909  $detailsoverview = $this->getPassDetailsOverview($result_array, $active_id, $pass, "iltestservicegui", "getResultsOfUserOutput", $command_solution_details);
910  }
911 
912  $user_id = $this->object->_getUserIdFromActiveId($active_id);
913  $showAllAnswers = TRUE;
914  if ($this->object->isExecutable($testSession, $user_id))
915  {
916  $showAllAnswers = FALSE;
917  }
918  if ($show_answers)
919  {
920  $list_of_answers = $this->getPassListOfAnswers($result_array, $active_id, $pass, FALSE, $showAllAnswers, $show_question_only, $show_reached_points);
921  }
922 
923  $template->setVariable("LIST_OF_ANSWERS", $list_of_answers);
924  //$template->setVariable("PASS_RESULTS_OVERVIEW", sprintf($this->lng->txt("tst_results_overview_pass"), $pass + 1));
925  $template->setVariable("PASS_DETAILS", $detailsoverview);
926 
927  $signature = $this->getResultsSignature();
928  $template->setVariable("SIGNATURE", $signature);
929 
930  if ($this->object->isShowExamIdInTestResultsEnabled())
931  {
932  $template->setCurrentBlock('exam_id_footer');
933  $template->setVariable('EXAM_ID_VAL', $this->object->lookupExamId(
934  $testSession->getActiveId(), $pass
935  ));
936  $template->setVariable('EXAM_ID_TXT', $this->lng->txt('exam_id'));
937  $template->parseCurrentBlock();
938  }
939  }
940  $template->setVariable("TEXT_HEADING", sprintf($this->lng->txt("tst_result_user_name"), $uname));
941  $template->setVariable("USER_DATA", $user_data);
942  $template->setVariable("USER_MARK", $statement["mark"]);
943  if (strlen($statement["markects"]))
944  {
945  $template->setVariable("USER_MARK_ECTS", $statement["markects"]);
946  }
947  $template->parseCurrentBlock();
948 
949  return $template->get();
950  }
951 
959  function getResultsHeadUserAndPass($active_id, $pass)
960  {
961  $template = new ilTemplate("tpl.il_as_tst_results_head_user_pass.html", TRUE, TRUE, "Modules/Test");
962  include_once './Services/User/classes/class.ilObjUser.php';
963  $user_id = $this->object->_getUserIdFromActiveId($active_id);
964  if (strlen(ilObjUser::_lookupLogin($user_id)) > 0)
965  {
966  $user = new ilObjUser($user_id);
967  }
968  else
969  {
970  $user = new ilObjUser();
971  $user->setLastname($this->lng->txt("deleted_user"));
972  }
973  $title_matric = "";
974  if (strlen($user->getMatriculation()) && (($this->object->getAnonymity() == FALSE)))
975  {
976  $template->setCurrentBlock("user_matric");
977  $template->setVariable("TXT_USR_MATRIC", $this->lng->txt("matriculation"));
978  $template->parseCurrentBlock();
979  $template->setCurrentBlock("user_matric_value");
980  $template->setVariable("VALUE_USR_MATRIC", $user->getMatriculation());
981  $template->parseCurrentBlock();
982  $template->touchBlock("user_matric_separator");
983  $title_matric = " - " . $this->lng->txt("matriculation") . ": " . $user->getMatriculation();
984  }
985 
986  $invited_user = array_pop($this->object->getInvitedUsers($user_id));
987  if (strlen($invited_user["clientip"]))
988  {
989  $template->setCurrentBlock("user_clientip");
990  $template->setVariable("TXT_CLIENT_IP", $this->lng->txt("client_ip"));
991  $template->parseCurrentBlock();
992  $template->setCurrentBlock("user_clientip_value");
993  $template->setVariable("VALUE_CLIENT_IP", $invited_user["clientip"]);
994  $template->parseCurrentBlock();
995  $template->touchBlock("user_clientip_separator");
996  $title_client = " - " . $this->lng->txt("clientip") . ": " . $invited_user["clientip"];
997  }
998 
999  $template->setVariable("TXT_USR_NAME", $this->lng->txt("name"));
1000  $uname = $this->object->userLookupFullName($user_id, FALSE);
1001  $template->setVariable("VALUE_USR_NAME", $uname);
1002  $template->setVariable("TXT_PASS", $this->lng->txt("scored_pass"));
1003  $template->setVariable("VALUE_PASS", $pass);
1004  return $template->get();
1005  }
1006 
1014  public function getQuestionResultForTestUsers($question_id, $test_id)
1015  {
1016  // REQUIRED, since we call this object regardless of the loop
1017  $question_gui =& $this->object->createQuestionGUI("", $question_id);
1018 
1019  $foundusers = $this->object->getParticipantsForTestAndQuestion($test_id, $question_id);
1020  $output = "";
1021  foreach ($foundusers as $active_id => $passes)
1022  {
1023  $resultpass = $this->object->_getResultPass($active_id);
1024  for ($i = 0; $i < count($passes); $i++)
1025  {
1026  if (($resultpass !== null) && ($resultpass == $passes[$i]["pass"]))
1027  {
1028  // check if re-instantiation is really neccessary
1029  $question_gui =& $this->object->createQuestionGUI("", $passes[$i]["qid"]);
1030 
1031  $output .= $this->getResultsHeadUserAndPass($active_id, $resultpass+1);
1032  $output .= $question_gui->getSolutionOutput(
1033  $active_id,
1034  $resultpass,
1035  $graphicalOutput = FALSE,
1036  $result_output = FALSE,
1037  $show_question_only = FALSE,
1038  $show_feedback = FALSE
1039  );
1040  $output .= "<br /><br /><br />";
1041  }
1042  }
1043  }
1044 
1045  require_once './Modules/Test/classes/class.ilTestPDFGenerator.php';
1046  ilTestPDFGenerator::generatePDF($output, ilTestPDFGenerator::PDF_OUTPUT_DOWNLOAD, $question_gui->object->getTitle());
1047  }
1048 }
1049 
1050 // internal sort function to sort the result array
1051 function sortResults($a, $b)
1052 {
1053  $sort = ($_GET["sort"]) ? ($_GET["sort"]) : "nr";
1054  $sortorder = ($_GET["sortorder"]) ? ($_GET["sortorder"]) : "asc";
1055  if (strcmp($sortorder, "asc"))
1056  {
1057  $smaller = 1;
1058  $greater = -1;
1059  }
1060  else
1061  {
1062  $smaller = -1;
1063  $greater = 1;
1064  }
1065  if ($a[$sort] == $b[$sort]) return 0;
1066  return ($a[$sort] < $b[$sort]) ? $smaller : $greater;
1067 }