ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilTestServiceGUI.php
Go to the documentation of this file.
1 <?php
2 
20 
21 include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
22 include_once 'Modules/Test/classes/class.ilTestService.php';
23 
39 {
40  protected const FIXED_SHUFFLER_SEED_MIN_LENGTH = 8;
41 
45  public $object = null;
46 
50  public $service = null;
51 
55  protected $db;
56 
60  protected $refinery;
61 
62  public $lng;
64  public $tpl;
65 
69  public $ctrl;
70 
74  protected $tabs;
75 
79  protected $objCache;
80 
81  public $ilias;
82  public $tree;
83  public $ref_id;
84 
90  protected $testSessionFactory = null;
91 
97  protected $testSequenceFactory = null;
98 
102  protected $participantData;
103 
108 
110 
114  public function isContextResultPresentation()
115  {
117  }
118 
123  {
124  $this->contextResultPresentation = $contextResultPresentation;
125  }
126 
133  public function __construct(ilObjTest $a_object)
134  {
135  global $DIC;
136  $lng = $DIC['lng'];
137  $refinery = $DIC['refinery'];
138  $tpl = $DIC['tpl'];
139  $ilCtrl = $DIC['ilCtrl'];
140  $ilias = $DIC['ilias'];
141  $tree = $DIC['tree'];
142  $ilDB = $DIC['ilDB'];
143  $ilPluginAdmin = $DIC['ilPluginAdmin'];
144  $ilTabs = $DIC['ilTabs'];
145  $ilObjDataCache = $DIC['ilObjDataCache'];
146 
147  $lng->loadLanguageModule('cert');
148 
149  $this->db = $ilDB;
150  $this->lng = &$lng;
151  $this->refinery = &$refinery;
152  $this->tpl = &$tpl;
153  $this->ctrl = &$ilCtrl;
154  $this->tabs = $ilTabs;
155  $this->objCache = $ilObjDataCache;
156  $this->ilias = &$ilias;
157  $this->object = &$a_object;
158  $this->tree = &$tree;
159  $this->ref_id = $a_object->ref_id;
160 
161  $this->service = new ilTestService($a_object);
162 
163  require_once 'Modules/Test/classes/class.ilTestSessionFactory.php';
164  $this->testSessionFactory = new ilTestSessionFactory($this->object);
165 
166  require_once 'Modules/Test/classes/class.ilTestSequenceFactory.php';
167  $this->testSequenceFactory = new ilTestSequenceFactory($ilDB, $lng, $refinery, $ilPluginAdmin, $this->object);
168  $this->objectiveOrientedContainer = null;
169  }
170 
175  {
176  $this->participantData = $participantData;
177  }
178 
182  public function getParticipantData()
183  {
184  return $this->participantData;
185  }
186 
192  public function getPassOverviewTableData(ilTestSession $testSession, $passes, $withResults)
193  {
194  $data = array();
195 
196  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
197  $considerHiddenQuestions = false;
198 
199  require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
200  $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($testSession);
201  } else {
202  $considerHiddenQuestions = true;
203  }
204 
205  $scoredPass = $this->object->_getResultPass($testSession->getActiveId());
206 
207  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
209  $testSession->getActiveId()
210  );
211 
212  foreach ($passes as $pass) {
213  $row = array();
214 
215  $considerOptionalQuestions = true;
216 
217  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
218  $testSequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($testSession->getActiveId(), $pass);
219 
220  $testSequence->loadFromDb();
221  $testSequence->loadQuestions();
222 
223  if ($this->object->isRandomTest() && !$testSequence->isAnsweringOptionalQuestionsConfirmed()) {
224  $considerOptionalQuestions = false;
225  }
226 
227  $testSequence->setConsiderHiddenQuestionsEnabled($considerHiddenQuestions);
228  $testSequence->setConsiderOptionalQuestionsEnabled($considerOptionalQuestions);
229 
230  $objectivesList = $this->buildQuestionRelatedObjectivesList($objectivesAdapter, $testSequence);
231  $objectivesList->loadObjectivesTitles();
232 
233  $row['objectives'] = $objectivesList->getUniqueObjectivesStringForQuestions($testSequence->getUserSequenceQuestions());
234  }
235 
236  if ($withResults) {
237  $result_array = $this->object->getTestResult($testSession->getActiveId(), $pass, false, $considerHiddenQuestions, $considerOptionalQuestions);
238 
239  foreach ($result_array as $resultStructKEY => $question) {
240  if ($resultStructKEY === 'test' || $resultStructKEY === 'pass') {
241  continue;
242  }
243 
244  $requestData = $questionHintRequestRegister->getRequestByTestPassIndexAndQuestionId($pass, $question['qid']);
245 
246  if ($requestData instanceof ilAssQuestionHintRequestStatisticData && $result_array[$resultStructKEY]['requested_hints'] === null) {
247  $result_array['pass']['total_requested_hints'] += $requestData->getRequestsCount();
248 
249  $result_array[$resultStructKEY]['requested_hints'] = $requestData->getRequestsCount();
250  $result_array[$resultStructKEY]['hint_points'] = $requestData->getRequestsPoints();
251  }
252  }
253 
254  if (!$result_array['pass']['total_max_points']) {
255  $percentage = 0;
256  } else {
257  $percentage = ($result_array['pass']['total_reached_points'] / $result_array['pass']['total_max_points']) * 100;
258  }
259  $total_max = $result_array['pass']['total_max_points'];
260  $total_reached = $result_array['pass']['total_reached_points'];
261  $total_requested_hints = $result_array['pass']['total_requested_hints'];
262  }
263 
264  if ($withResults) {
265  $row['scored'] = ($pass == $scoredPass);
266  }
267 
268  $row['pass'] = $pass;
269  $row['date'] = ilObjTest::lookupLastTestPassAccess($testSession->getActiveId(), $pass);
270  if ($withResults) {
271  $row['num_workedthrough_questions'] = $result_array['pass']['num_workedthrough'];
272  $row['num_questions_total'] = $result_array['pass']['num_questions_total'];
273 
274  if ($this->object->isOfferingQuestionHintsEnabled()) {
275  $row['hints'] = $total_requested_hints;
276  }
277 
278  $row['reached_points'] = $total_reached;
279  $row['max_points'] = $total_max;
280  $row['percentage'] = $percentage;
281  }
282 
283  $data[] = $row;
284  }
285 
286  return $data;
287  }
288 
293  {
294  $this->objectiveOrientedContainer = $objectiveOrientedContainer;
295  }
296 
301  {
303  }
304 
308  public function executeCommand()
309  {
310  $cmd = $this->ctrl->getCmd();
311  $next_class = $this->ctrl->getNextClass($this);
312 
313  $cmd = $this->getCommand($cmd);
314  switch ($next_class) {
315  default:
316  $ret = &$this->$cmd();
317  break;
318  }
319  return $ret;
320  }
321 
327  public function getCommand($cmd)
328  {
329  return $cmd;
330  }
331 
335  protected function isPdfDeliveryRequest()
336  {
337  if (!isset($_GET['pdf'])) {
338  return false;
339  }
340 
341  if (!(bool) $_GET['pdf']) {
342  return false;
343  }
344 
345  return true;
346  }
347 
351  public function buildPassOverviewTableGUI($targetGUI)
352  {
353  require_once 'Modules/Test/classes/tables/class.ilTestPassOverviewTableGUI.php';
354 
355  $table = new ilTestPassOverviewTableGUI($targetGUI, '');
356 
357  $table->setPdfPresentationEnabled(
358  isset($_GET['pdf']) && $_GET['pdf'] == 1
359  );
360 
361  $table->setObjectiveOrientedPresentationEnabled(
362  $this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()
363  );
364 
365  return $table;
366  }
367 
378  public function getPassListOfAnswers(&$result_array, $active_id, $pass, $show_solutions = false, $only_answered_questions = false, $show_question_only = false, $show_reached_points = false, $anchorNav = false, ilTestQuestionRelatedObjectivesList $objectivesList = null, ilTestResultHeaderLabelBuilder $testResultHeaderLabelBuilder = null)
379  {
380  $maintemplate = new ilTemplate("tpl.il_as_tst_list_of_answers.html", true, true, "Modules/Test");
381 
382  $counter = 1;
383  // output of questions with solutions
384  foreach ($result_array as $question_data) {
385  if (($question_data["workedthrough"] == 1) || ($only_answered_questions == false)) {
386  $template = new ilTemplate("tpl.il_as_qpl_question_printview.html", true, true, "Modules/TestQuestionPool");
387  $question_id = $question_data["qid"];
388  if (is_numeric($question_id)) {
389  $maintemplate->setCurrentBlock("printview_question");
390  $question_gui = $this->object->createQuestionGUI("", $question_id);
391  $question_gui->object->setShuffler($this->buildQuestionAnswerShuffler((string) $question_id, (string) $active_id, (string) $pass));
392  if (is_object($question_gui)) {
393  if ($this->isPdfDeliveryRequest()) {
394  $question_gui->setRenderPurpose(assQuestionGUI::RENDER_PURPOSE_PRINT_PDF);
395  }
396 
397  if ($anchorNav) {
398  $template->setCurrentBlock('block_id');
399  $template->setVariable('BLOCK_ID', "detailed_answer_block_act_{$active_id}_qst_{$question_id}");
400  $template->parseCurrentBlock();
401 
402  $template->setCurrentBlock('back_anchor');
403  $template->setVariable('HREF_BACK_ANCHOR', "#pass_details_tbl_row_act_{$active_id}_qst_{$question_id}");
404  $template->setVariable('TXT_BACK_ANCHOR', $this->lng->txt('tst_back_to_question_list'));
405  $template->parseCurrentBlock();
406  }
407 
408  if ($show_reached_points) {
409  $template->setCurrentBlock("result_points");
410  $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());
411  $template->parseCurrentBlock();
412  }
413  $template->setVariable("COUNTER_QUESTION", $counter . ". ");
414  $template->setVariable("TXT_QUESTION_ID", $this->lng->txt('question_id_short'));
415  $template->setVariable("QUESTION_ID", $question_gui->object->getId());
416  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitle()));
417 
418  if ($objectivesList !== null) {
419  $objectives = $this->lng->txt('tst_res_lo_objectives_header') . ': ';
420  $objectives .= $objectivesList->getQuestionRelatedObjectiveTitles($question_gui->object->getId());
421  $template->setVariable("OBJECTIVES", $objectives);
422  }
423 
424  $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? true : false;
425 
426  $show_feedback = $this->isContextResultPresentation() && $this->object->getShowSolutionFeedback();
427  $show_best_solution = $this->isContextResultPresentation() && $show_solutions;
428  $show_graphical_output = $this->isContextResultPresentation();
429 
430  if ($show_best_solution) {
431  $compare_template = new ilTemplate('tpl.il_as_tst_answers_compare.html', true, true, 'Modules/Test');
432  $test_session = $this->testSessionFactory->getSession($active_id);
433  if ($pass <= $test_session->getLastFinishedPass()) {
434  $compare_template->setVariable("HEADER_PARTICIPANT", $this->lng->txt('tst_header_participant'));
435  } else {
436  $compare_template->setVariable("HEADER_PARTICIPANT", $this->lng->txt('tst_header_participant_no_answer'));
437  }
438 
439  $compare_template->setVariable("HEADER_SOLUTION", $this->lng->txt('tst_header_solution'));
440  $result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_graphical_output, false, $show_question_only, $show_feedback);
441  $best_output = $question_gui->getSolutionOutput($active_id, $pass, false, false, $show_question_only, false, true);
442 
443  $compare_template->setVariable('PARTICIPANT', $result_output);
444  $compare_template->setVariable('SOLUTION', $best_output);
445  if ($question_gui->supportsIntermediateSolutionOutput() && $question_gui->hasIntermediateSolution($active_id, $pass)) {
446  $question_gui->setUseIntermediateSolution(true);
447  $intermediate_output = $question_gui->getSolutionOutput($active_id, $pass, $show_graphical_output, false, true, $show_feedback);
448  $question_gui->setUseIntermediateSolution(false);
449  $compare_template->setVariable('TXT_INTERMEDIATE', $this->lng->txt('autosavecontent'));
450  $compare_template->setVariable('INTERMEDIATE', $intermediate_output);
451  }
452  $template->setVariable('SOLUTION_OUTPUT', $compare_template->get());
453  } else {
454  $result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_graphical_output, false, $show_question_only, $show_feedback);
455  if ($question_gui->supportsIntermediateSolutionOutput() && $question_gui->hasIntermediateSolution($active_id, $pass)) {
456  $question_gui->setUseIntermediateSolution(true);
457  $intermediate_output = $question_gui->getSolutionOutput($active_id, $pass, $show_graphical_output, false, true, $show_feedback);
458  $question_gui->setUseIntermediateSolution(false);
459  $template->setVariable('TXT_INTERMEDIATE', $this->lng->txt('autosavecontent'));
460  $template->setVariable('INTERMEDIATE', $intermediate_output);
461  }
462  $template->setVariable('SOLUTION_OUTPUT', $result_output);
463  }
464 
465  $maintemplate->setCurrentBlock("printview_question");
466  $maintemplate->setVariable("QUESTION_PRINTVIEW", $template->get());
467  $maintemplate->parseCurrentBlock();
468  $counter++;
469  }
470  }
471  }
472  }
473 
474  if ($testResultHeaderLabelBuilder !== null) {
475  if ($pass !== null) {
476  $headerText = $testResultHeaderLabelBuilder->getListOfAnswersHeaderLabel($pass + 1);
477  } else {
478  $headerText = $testResultHeaderLabelBuilder->getVirtualListOfAnswersHeaderLabel();
479  }
480  } else {
481  $headerText = '';
482  }
483 
484  $maintemplate->setVariable("RESULTS_OVERVIEW", $headerText);
485  return $maintemplate->get();
486  }
487 
488  protected function buildQuestionAnswerShuffler(string $question_id, string $active_id, string $active_pass) : ilArrayElementShuffler
489  {
490  $shuffler = new ilArrayElementShuffler();
491 
492  $fixed_seed = $this->buildFixedShufflerSeedFromBasicSeed($question_id . $active_id . $active_pass);
493  $shuffler->setSeed($fixed_seed);
494 
495  return $shuffler;
496  }
497 
502  protected function buildFixedShufflerSeedFromBasicSeed(string $basic_seed) : string
503  {
504  $fixed_seed = $basic_seed;
505 
506  if (strlen($fixed_seed) < self::FIXED_SHUFFLER_SEED_MIN_LENGTH) {
507  $fixed_seed *= (
508  10 * (self::FIXED_SHUFFLER_SEED_MIN_LENGTH - strlen($fixed_seed))
509  );
510  }
511 
512  return $fixed_seed;
513  }
514 
527  public function getPassListOfAnswersWithScoring(&$result_array, $active_id, $pass, $show_solutions = false)
528  {
529  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
530 
531  $maintemplate = new ilTemplate("tpl.il_as_tst_list_of_answers.html", true, true, "Modules/Test");
532 
533  include_once "./Modules/Test/classes/class.ilObjAssessmentFolder.php";
535 
536  $counter = 1;
537  // output of questions with solutions
538  foreach ($result_array as $question_data) {
539  $question = $question_data["qid"];
540  if (is_numeric($question)) {
541  $question_gui = $this->object->createQuestionGUI("", $question);
542  if (in_array($question_gui->object->getQuestionTypeID(), $scoring)) {
543  $template = new ilTemplate("tpl.il_as_qpl_question_printview.html", true, true, "Modules/TestQuestionPool");
544  $scoretemplate = new ilTemplate("tpl.il_as_tst_manual_scoring_points.html", true, true, "Modules/Test");
545  #mbecker: No such block. $this->tpl->setCurrentBlock("printview_question");
546  $template->setVariable("COUNTER_QUESTION", $counter . ". ");
547  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitle()));
548  $points = $question_gui->object->getMaximumPoints();
549  if ($points == 1) {
550  $template->setVariable("QUESTION_POINTS", $points . " " . $this->lng->txt("point"));
551  } else {
552  $template->setVariable("QUESTION_POINTS", $points . " " . $this->lng->txt("points"));
553  }
554 
555  $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? true : false;
556  $result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_solutions, false, $show_question_only, $this->object->getShowSolutionFeedback(), false, true);
557 
558  $solout = $question_gui->object->getSuggestedSolutionOutput();
559  if (strlen($solout)) {
560  $scoretemplate->setCurrentBlock("suggested_solution");
561  $scoretemplate->setVariable("TEXT_SUGGESTED_SOLUTION", $this->lng->txt("solution_hint"));
562  $scoretemplate->setVariable("VALUE_SUGGESTED_SOLUTION", $solout);
563  $scoretemplate->parseCurrentBlock();
564  }
565 
566  $scoretemplate->setCurrentBlock("feedback");
567  $scoretemplate->setVariable("FEEDBACK_NAME_INPUT", $question);
568  $feedback = $this->object->getSingleManualFeedback($active_id, $question, $pass)['feedback'];
569  $scoretemplate->setVariable("VALUE_FEEDBACK", ilUtil::prepareFormOutput($this->object->prepareTextareaOutput($feedback, true)));
570  $scoretemplate->setVariable("TEXT_MANUAL_FEEDBACK", $this->lng->txt("set_manual_feedback"));
571  $scoretemplate->parseCurrentBlock();
572 
573  $scoretemplate->setVariable("NAME_INPUT", $question);
574  $this->ctrl->setParameter($this, "active_id", $active_id);
575  $this->ctrl->setParameter($this, "pass", $pass);
576  $scoretemplate->setVariable("FORMACTION", $this->ctrl->getFormAction($this, "manscoring"));
577  $scoretemplate->setVariable("LABEL_INPUT", $this->lng->txt("tst_change_points_for_question"));
578  $scoretemplate->setVariable("VALUE_INPUT", " value=\"" . assQuestion::_getReachedPoints($active_id, $question_data["qid"], $pass) . "\"");
579  $scoretemplate->setVariable("VALUE_SAVE", $this->lng->txt("save"));
580 
581  $template->setVariable("SOLUTION_OUTPUT", $result_output);
582  $maintemplate->setCurrentBlock("printview_question");
583  $maintemplate->setVariable("QUESTION_PRINTVIEW", $template->get());
584  $maintemplate->setVariable("QUESTION_SCORING", $scoretemplate->get());
585  $maintemplate->parseCurrentBlock();
586  }
587  $counter++;
588  }
589  }
590  if ($counter == 1) {
591  // no scorable questions found
592  $maintemplate->setVariable("NO_QUESTIONS_FOUND", $this->lng->txt("manscoring_questions_not_found"));
593  }
594  $maintemplate->setVariable("RESULTS_OVERVIEW", sprintf($this->lng->txt("manscoring_results_pass"), $pass + 1));
595 
596  include_once "./Services/YUI/classes/class.ilYuiUtil.php";
598 
599  return $maintemplate->get();
600  }
601 
602  protected function getPassDetailsOverviewTableGUI($result_array, $active_id, $pass, $targetGUI, $targetCMD, $questionDetailsCMD, $questionAnchorNav, ilTestQuestionRelatedObjectivesList $objectivesList = null, $multipleObjectivesInvolved = true)
603  {
604  $this->ctrl->setParameter($targetGUI, 'active_id', $active_id);
605  $this->ctrl->setParameter($targetGUI, 'pass', $pass);
606 
607  $tableGUI = $this->buildPassDetailsOverviewTableGUI($targetGUI, $targetCMD);
608 
609  if (!$this->isPdfDeliveryRequest()) {
610  $tableGUI->setAnswerListAnchorEnabled($questionAnchorNav);
611  }
612 
613  $tableGUI->setSingleAnswerScreenCmd($questionDetailsCMD);
614  $tableGUI->setShowHintCount($this->object->isOfferingQuestionHintsEnabled());
615 
616  if ($objectivesList !== null) {
617  $tableGUI->setQuestionRelatedObjectivesList($objectivesList);
618  $tableGUI->setObjectiveOrientedPresentationEnabled(true);
619  }
620 
621  $tableGUI->setMultipleObjectivesInvolved($multipleObjectivesInvolved);
622 
623  $tableGUI->setActiveId($active_id);
624  $tableGUI->setShowSuggestedSolution(false);
625 
626  $usersQuestionSolutions = array();
627 
628  foreach ($result_array as $key => $val) {
629  if ($key === 'test' || $key === 'pass') {
630  continue;
631  }
632 
633  if ($this->object->getShowSolutionSuggested() && strlen($val['solution'])) {
634  $tableGUI->setShowSuggestedSolution(true);
635  }
636 
637  if (isset($val['pass'])) {
638  $tableGUI->setPassColumnEnabled(true);
639  }
640 
641  $usersQuestionSolutions[$key] = $val;
642  }
643 
644  $tableGUI->initColumns()->initFilter();
645 
646  $tableGUI->setFilterCommand($targetCMD . 'SetTableFilter');
647  $tableGUI->setResetCommand($targetCMD . 'ResetTableFilter');
648 
649  $tableGUI->setData($usersQuestionSolutions);
650 
651  return $tableGUI;
652  }
653 
660  public function getResultsSignature()
661  {
662  if ($this->object->getShowSolutionSignature() && !$this->object->getAnonymity()) {
663  $template = new ilTemplate("tpl.il_as_tst_results_userdata_signature.html", true, true, "Modules/Test");
664  $template->setVariable("TXT_DATE", $this->lng->txt("date"));
667  $template->setVariable("VALUE_DATE", ilDatePresentation::formatDate(new ilDate(time(), IL_CAL_UNIX)));
669  $template->setVariable("TXT_SIGNATURE", $this->lng->txt("tst_signature"));
670  $template->setVariable("IMG_SPACER", ilUtil::getImagePath("spacer.png"));
671  return $template->get();
672  } else {
673  return "";
674  }
675  }
676 
686  public function getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, $overwrite_anonymity = false)
687  {
688  if (!is_object($testSession)) {
689  throw new TestException();
690  }
691  $template = new ilTemplate("tpl.il_as_tst_results_userdata.html", true, true, "Modules/Test");
692  include_once './Services/User/classes/class.ilObjUser.php';
693  $user_id = $this->object->_getUserIdFromActiveId($active_id);
694  if (strlen(ilObjUser::_lookupLogin($user_id)) > 0) {
695  $user = new ilObjUser($user_id);
696  } else {
697  $user = new ilObjUser();
698  $user->setLastname($this->lng->txt("deleted_user"));
699  }
700  $t = $testSession->getSubmittedTimestamp();
701  if (!$t) {
702  $t = $this->object->_getLastAccess($testSession->getActiveId());
703  }
704 
705  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
706  $uname = $this->object->userLookupFullName($user_id, $overwrite_anonymity);
707  $template->setCurrentBlock("name");
708  $template->setVariable('TXT_USR_NAME', $this->lng->txt("name"));
709  $template->setVariable('VALUE_USR_NAME', $uname);
710  $template->parseCurrentBlock();
711  }
712 
713  $title_matric = "";
714  if (strlen($user->getMatriculation()) && (($this->object->getAnonymity() == false) || ($overwrite_anonymity))) {
715  $template->setCurrentBlock("matriculation");
716  $template->setVariable("TXT_USR_MATRIC", $this->lng->txt("matriculation"));
717  $template->setVariable("VALUE_USR_MATRIC", $user->getMatriculation());
718  $template->parseCurrentBlock();
719  $title_matric = " - " . $this->lng->txt("matriculation") . ": " . $user->getMatriculation();
720  }
721 
722  $invited_user = array_pop($this->object->getInvitedUsers($user_id));
723  if (strlen($invited_user["clientip"])) {
724  $template->setCurrentBlock("client_ip");
725  $template->setVariable("TXT_CLIENT_IP", $this->lng->txt("client_ip"));
726  $template->setVariable("VALUE_CLIENT_IP", $invited_user["clientip"]);
727  $template->parseCurrentBlock();
728  $title_client = " - " . $this->lng->txt("clientip") . ": " . $invited_user["clientip"];
729  }
730 
731  $template->setVariable("TXT_TEST_TITLE", $this->lng->txt("title"));
732  $template->setVariable("VALUE_TEST_TITLE", $this->object->getTitle());
733 
734  // change the pagetitle (tab title or title in title bar of window)
735  $pagetitle = $this->object->getTitle() . $title_matric . $title_client;
736  $this->tpl->setHeaderPageTitle($pagetitle);
737 
738  return $template->get();
739  }
740 
750  public function getCorrectSolutionOutput($question_id, $active_id, $pass, ilTestQuestionRelatedObjectivesList $objectivesList = null)
751  {
752  global $DIC;
753  $ilUser = $DIC['ilUser'];
754 
755  $test_id = $this->object->getTestId();
756  $question_gui = $this->object->createQuestionGUI("", $question_id);
757 
758  if ($this->isPdfDeliveryRequest()) {
759  $question_gui->setRenderPurpose(assQuestionGUI::RENDER_PURPOSE_PRINT_PDF);
760  }
761 
762  $template = new ilTemplate("tpl.il_as_tst_correct_solution_output.html", true, true, "Modules/Test");
763  $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? true : false;
764  $result_output = $question_gui->getSolutionOutput($active_id, $pass, true, false, $show_question_only, $this->object->getShowSolutionFeedback(), false, false, true);
765  $best_output = $question_gui->getSolutionOutput($active_id, $pass, false, false, $show_question_only, false, true, false, false);
766  if ($this->object->getShowSolutionFeedback() && $_GET['cmd'] != 'outCorrectSolution') {
767  $specificAnswerFeedback = $question_gui->getSpecificFeedbackOutput(
768  $question_gui->object->fetchIndexedValuesFromValuePairs(
769  $question_gui->object->getSolutionValues($active_id, $pass)
770  )
771  );
772  if (strlen($specificAnswerFeedback)) {
773  $template->setCurrentBlock("outline_specific_feedback");
774  $template->setVariable("OUTLINE_SPECIFIC_FEEDBACK", $specificAnswerFeedback);
775  $template->parseCurrentBlock();
776  }
777  }
778  if ($this->object->isBestSolutionPrintedWithResult() && strlen($best_output)) {
779  $template->setCurrentBlock("best_solution");
780  $template->setVariable("TEXT_BEST_SOLUTION", $this->lng->txt("tst_best_solution_is"));
781  $template->setVariable("BEST_OUTPUT", $best_output);
782  $template->parseCurrentBlock();
783  }
784  $template->setVariable("TEXT_YOUR_SOLUTION", $this->lng->txt("tst_your_answer_was"));
785  $template->setVariable("TEXT_SOLUTION_OUTPUT", $this->lng->txt("tst_your_answer_was")); // Mantis 28646. I don't really know why Ingmar renamed the placeholder, so
786  // I set both old and new since the old one is set as well in several places.
787  $maxpoints = $question_gui->object->getMaximumPoints();
788  if ($maxpoints == 1) {
789  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitle()) . " (" . $maxpoints . " " . $this->lng->txt("point") . ")");
790  } else {
791  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitle()) . " (" . $maxpoints . " " . $this->lng->txt("points") . ")");
792  }
793  if ($objectivesList !== null) {
794  $objectives = $this->lng->txt('tst_res_lo_objectives_header') . ': ';
795  $objectives .= $objectivesList->getQuestionRelatedObjectiveTitles($question_gui->object->getId());
796  $template->setVariable('OBJECTIVES', $objectives);
797  }
798  $template->setVariable("SOLUTION_OUTPUT", $result_output);
799  $template->setVariable("RECEIVED_POINTS", sprintf($this->lng->txt("you_received_a_of_b_points"), $question_gui->object->getReachedPoints($active_id, $pass), $maxpoints));
800  $template->setVariable("FORMACTION", $this->ctrl->getFormAction($this));
801  $template->setVariable("BACKLINK_TEXT", "&lt;&lt; " . $this->lng->txt("back"));
802  return $template->get();
803  }
804 
817  public function getResultsOfUserOutput($testSession, $active_id, $pass, $targetGUI, $show_pass_details = true, $show_answers = true, $show_question_only = false, $show_reached_points = false)
818  {
819  global $DIC;
820  $ilObjDataCache = $DIC['ilObjDataCache'];
821 
822  include_once("./Services/UICore/classes/class.ilTemplate.php");
823  $template = new ilTemplate("tpl.il_as_tst_results_participant.html", true, true, "Modules/Test");
824 
825  if ($this->participantData instanceof ilTestParticipantData) {
826  $user_id = $this->participantData->getUserIdByActiveId($active_id);
827  $uname = $this->participantData->getConcatedFullnameByActiveId($active_id, false);
828  } else {
829  $user_id = $this->object->_getUserIdFromActiveId($active_id);
830  $uname = $this->object->userLookupFullName($user_id, true);
831  }
832 
833  if ($this->object->getAnonymity()) {
834  $uname = $this->lng->txt('anonymous');
835  }
836 
837  if (((array_key_exists("pass", $_GET)) && (strlen($_GET["pass"]) > 0)) || (!is_null($pass))) {
838  if (is_null($pass)) {
839  $pass = $_GET["pass"];
840  }
841  }
842 
843  if (!is_null($pass)) {
844  require_once 'Modules/Test/classes/class.ilTestResultHeaderLabelBuilder.php';
845  $testResultHeaderLabelBuilder = new ilTestResultHeaderLabelBuilder($this->lng, $ilObjDataCache);
846  $objectivesList = null;
847 
848  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
849  $testSequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($active_id, $pass);
850  $testSequence->loadFromDb();
851  $testSequence->loadQuestions();
852 
853  require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
854  $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($testSession);
855 
856  $objectivesList = $this->buildQuestionRelatedObjectivesList($objectivesAdapter, $testSequence);
857  $objectivesList->loadObjectivesTitles();
858 
859  $testResultHeaderLabelBuilder->setObjectiveOrientedContainerId($testSession->getObjectiveOrientedContainerId());
860  $testResultHeaderLabelBuilder->setUserId($testSession->getUserId());
861  $testResultHeaderLabelBuilder->setTestObjId($this->object->getId());
862  $testResultHeaderLabelBuilder->setTestRefId($this->object->getRefId());
863  $testResultHeaderLabelBuilder->initObjectiveOrientedMode();
864  }
865 
866  $result_array = $this->object->getTestResult(
867  $active_id,
868  $pass,
869  false,
870  !$this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()
871  );
872 
873  $user_id = $this->object->_getUserIdFromActiveId($active_id);
874  $showAllAnswers = true;
875  if ($this->object->isExecutable($testSession, $user_id)) {
876  $showAllAnswers = false;
877  }
878  if ($show_answers) {
879  $list_of_answers = $this->getPassListOfAnswers(
880  $result_array,
881  $active_id,
882  $pass,
883  $_SESSION['tst_results_show_best_solutions'],
884  $showAllAnswers,
885  $show_question_only,
886  $show_reached_points,
887  $show_pass_details,
888  $objectivesList,
889  $testResultHeaderLabelBuilder
890  );
891  $template->setVariable("LIST_OF_ANSWERS", $list_of_answers);
892  }
893 
894  if ($show_pass_details) {
895  $overviewTableGUI = $this->getPassDetailsOverviewTableGUI($result_array, $active_id, $pass, $targetGUI, "getResultsOfUserOutput", '', $show_answers, $objectivesList);
896  $overviewTableGUI->setTitle($testResultHeaderLabelBuilder->getPassDetailsHeaderLabel($pass + 1));
897  $template->setVariable("PASS_DETAILS", $overviewTableGUI->getHTML());
898  }
899 
900  $signature = $this->getResultsSignature();
901  $template->setVariable("SIGNATURE", $signature);
902 
903  if ($this->object->isShowExamIdInTestResultsEnabled()) {
904  $template->setCurrentBlock('exam_id_footer');
905  $template->setVariable('EXAM_ID_VAL', ilObjTest::lookupExamId(
906  $testSession->getActiveId(),
907  $pass
908  ));
909  $template->setVariable('EXAM_ID_TXT', $this->lng->txt('exam_id'));
910  $template->parseCurrentBlock();
911  }
912  }
913 
914  $template->setCurrentBlock('participant_back_anchor');
915  $template->setVariable("HREF_PARTICIPANT_BACK_ANCHOR", "#tst_results_toolbar");
916  $template->setVariable("TXT_PARTICIPANT_BACK_ANCHOR", $this->lng->txt('tst_back_to_top'));
917  $template->parseCurrentBlock();
918 
919  $template->setCurrentBlock('participant_block_id');
920  $template->setVariable("PARTICIPANT_BLOCK_ID", "participant_active_{$active_id}");
921  $template->parseCurrentBlock();
922 
923  if ($this->isGradingMessageRequired()) {
924  $gradingMessageBuilder = $this->getGradingMessageBuilder($active_id);
925  $gradingMessageBuilder->buildList();
926 
927  $template->setCurrentBlock('grading_message');
928  $template->setVariable('GRADING_MESSAGE', $gradingMessageBuilder->getList());
929  $template->parseCurrentBlock();
930  }
931 
932 
933  $user_data = $this->getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, true);
934  $template->setVariable("TEXT_HEADING", sprintf($this->lng->txt("tst_result_user_name"), $uname));
935  $template->setVariable("USER_DATA", $user_data);
936 
937  $this->populateExamId($template, (int) $active_id, (int) $pass);
938  $this->populatePassFinishDate($template, ilObjTest::lookupLastTestPassAccess($active_id, $pass));
939 
940  return $template->get();
941  }
942 
950  public function getResultsHeadUserAndPass($active_id, $pass)
951  {
952  $template = new ilTemplate("tpl.il_as_tst_results_head_user_pass.html", true, true, "Modules/Test");
953  include_once './Services/User/classes/class.ilObjUser.php';
954  $user_id = $this->object->_getUserIdFromActiveId($active_id);
955  if (strlen(ilObjUser::_lookupLogin($user_id)) > 0) {
956  $user = new ilObjUser($user_id);
957  } else {
958  $user = new ilObjUser();
959  $user->setLastname($this->lng->txt("deleted_user"));
960  }
961  $title_matric = "";
962  if (strlen($user->getMatriculation()) && (($this->object->getAnonymity() == false))) {
963  $template->setCurrentBlock("user_matric");
964  $template->setVariable("TXT_USR_MATRIC", $this->lng->txt("matriculation"));
965  $template->parseCurrentBlock();
966  $template->setCurrentBlock("user_matric_value");
967  $template->setVariable("VALUE_USR_MATRIC", $user->getMatriculation());
968  $template->parseCurrentBlock();
969  $template->touchBlock("user_matric_separator");
970  $title_matric = " - " . $this->lng->txt("matriculation") . ": " . $user->getMatriculation();
971  }
972 
973  $invited_user = array_pop($this->object->getInvitedUsers($user_id));
974  if (strlen($invited_user["clientip"])) {
975  $template->setCurrentBlock("user_clientip");
976  $template->setVariable("TXT_CLIENT_IP", $this->lng->txt("client_ip"));
977  $template->parseCurrentBlock();
978  $template->setCurrentBlock("user_clientip_value");
979  $template->setVariable("VALUE_CLIENT_IP", $invited_user["clientip"]);
980  $template->parseCurrentBlock();
981  $template->touchBlock("user_clientip_separator");
982  $title_client = " - " . $this->lng->txt("clientip") . ": " . $invited_user["clientip"];
983  }
984 
985  $template->setVariable("TXT_USR_NAME", $this->lng->txt("name"));
986  $uname = $this->object->userLookupFullName($user_id, false);
987  $template->setVariable("VALUE_USR_NAME", $uname);
988  $template->setVariable("TXT_PASS", $this->lng->txt("scored_pass"));
989  $template->setVariable("VALUE_PASS", $pass);
990  return $template->get();
991  }
992 
1000  public function getQuestionResultForTestUsers($question_id, $test_id)
1001  {
1002  // prepare generation before contents are processed (for mathjax)
1004 
1005  // REQUIRED, since we call this object regardless of the loop
1006  $question_gui = $this->object->createQuestionGUI("", $question_id);
1007 
1008  $this->object->setAccessFilteredParticipantList(
1009  $this->object->buildStatisticsAccessFilteredParticipantList()
1010  );
1011 
1012  $foundusers = $this->object->getParticipantsForTestAndQuestion($test_id, $question_id);
1013  $output = '';
1014  foreach ($foundusers as $active_id => $passes) {
1015  $resultpass = $this->object->_getResultPass($active_id);
1016  for ($i = 0; $i < count($passes); $i++) {
1017  if (($resultpass !== null) && ($resultpass == $passes[$i]["pass"])) {
1018  if ($output) {
1019  $output .= "<br /><br /><br />";
1020  }
1021 
1022  // check if re-instantiation is really neccessary
1023  $question_gui = $this->object->createQuestionGUI("", $passes[$i]["qid"]);
1024  $output .= $this->getResultsHeadUserAndPass($active_id, $resultpass + 1);
1025  $question_gui->setRenderPurpose(assQuestionGUI::RENDER_PURPOSE_PRINT_PDF);
1026  $output .= $question_gui->getSolutionOutput(
1027  $active_id,
1028  $resultpass,
1029  $graphicalOutput = false,
1030  $result_output = false,
1031  $show_question_only = false,
1032  $show_feedback = false
1033  );
1034  }
1035  }
1036  }
1037 
1038  require_once './Modules/Test/classes/class.ilTestPDFGenerator.php';
1039  ilTestPDFGenerator::generatePDF($output, ilTestPDFGenerator::PDF_OUTPUT_DOWNLOAD, $question_gui->object->getTitleFilenameCompliant(), PDF_USER_RESULT);
1040  }
1041 
1045  protected function buildPassDetailsOverviewTableGUI($targetGUI, $targetCMD)
1046  {
1047  if (!isset($targetGUI->object) && method_exists($targetGUI, 'getTestObj')) {
1048  $targetGUI->object = $targetGUI->getTestObj();
1049  }
1050 
1051  require_once 'Modules/Test/classes/tables/class.ilTestPassDetailsOverviewTableGUI.php';
1052  $tableGUI = new ilTestPassDetailsOverviewTableGUI($this->ctrl, $targetGUI, $targetCMD);
1053  $tableGUI->setIsPdfGenerationRequest($this->isPdfDeliveryRequest());
1054  return $tableGUI;
1055  }
1056 
1057  protected function isGradingMessageRequired()
1058  {
1059  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
1060  return false;
1061  }
1062 
1063  if ($this->object->isShowGradingStatusEnabled()) {
1064  return true;
1065  }
1066 
1067  if ($this->object->isShowGradingMarkEnabled()) {
1068  return true;
1069  }
1070 
1071  if ($this->object->areObligationsEnabled()) {
1072  return true;
1073  }
1074 
1075  return false;
1076  }
1077 
1082  protected function getGradingMessageBuilder($activeId)
1083  {
1084  require_once 'Modules/Test/classes/class.ilTestGradingMessageBuilder.php';
1085  $gradingMessageBuilder = new ilTestGradingMessageBuilder($this->lng, $this->object);
1086 
1087  $gradingMessageBuilder->setActiveId($activeId);
1088 
1089  return $gradingMessageBuilder;
1090  }
1091 
1092  protected function buildQuestionRelatedObjectivesList(ilLOTestQuestionAdapter $objectivesAdapter, ilTestQuestionSequence $testSequence)
1093  {
1094  require_once 'Modules/Test/classes/class.ilTestQuestionRelatedObjectivesList.php';
1095  $questionRelatedObjectivesList = new ilTestQuestionRelatedObjectivesList();
1096 
1097  $objectivesAdapter->buildQuestionRelatedObjectiveList($testSequence, $questionRelatedObjectivesList);
1098 
1099  return $questionRelatedObjectivesList;
1100  }
1101 
1102  protected function getFilteredTestResult($active_id, $pass, $considerHiddenQuestions, $considerOptionalQuestions)
1103  {
1104  global $DIC;
1105  $ilDB = $DIC['ilDB'];
1106  $ilPluginAdmin = $DIC['ilPluginAdmin'];
1107 
1108  $table_gui = $this->buildPassDetailsOverviewTableGUI($this, 'outUserPassDetails');
1109  $table_gui->initFilter();
1110 
1111  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionList.php';
1112  $questionList = new ilAssQuestionList($ilDB, $this->lng, $this->refinery, $ilPluginAdmin);
1113 
1114  $questionList->setParentObjIdsFilter(array($this->object->getId()));
1115  $questionList->setQuestionInstanceTypeFilter(ilAssQuestionList::QUESTION_INSTANCE_TYPE_DUPLICATES);
1116 
1117  foreach ($table_gui->getFilterItems() as $item) {
1118  if (substr($item->getPostVar(), 0, strlen('tax_')) == 'tax_') {
1119  $v = $item->getValue();
1120 
1121  if (is_array($v) && count($v) && !(int) $v[0]) {
1122  continue;
1123  }
1124 
1125  $taxId = substr($item->getPostVar(), strlen('tax_'));
1126  $questionList->addTaxonomyFilter($taxId, $item->getValue(), $this->object->getId(), 'tst');
1127  } elseif ($item->getValue() !== false) {
1128  $questionList->addFieldFilter($item->getPostVar(), $item->getValue());
1129  }
1130  }
1131 
1132  $questionList->load();
1133 
1134  $filteredTestResult = array();
1135 
1136  $resultData = $this->object->getTestResult($active_id, $pass, false, $considerHiddenQuestions, $considerOptionalQuestions);
1137 
1138  foreach ($resultData as $resultItemKey => $resultItemValue) {
1139  if ($resultItemKey === 'test' || $resultItemKey === 'pass') {
1140  continue;
1141  }
1142 
1143  if (!$questionList->isInList($resultItemValue['qid'])) {
1144  continue;
1145  }
1146 
1147  $filteredTestResult[] = $resultItemValue;
1148  }
1149 
1150  return $filteredTestResult;
1151  }
1152 
1156  protected function populateContent($content)
1157  {
1158  if ($this->isPdfDeliveryRequest()) {
1160  $content,
1162  $this->object->getTitleFilenameCompliant(),
1164  );
1165  } else {
1166  $this->tpl->setContent($content);
1167  }
1168  }
1169 
1173  protected function buildUserTestResultsToolbarGUI()
1174  {
1175  require_once 'Modules/Test/classes/toolbars/class.ilTestResultsToolbarGUI.php';
1176  $toolbar = new ilTestResultsToolbarGUI($this->ctrl, $this->tpl, $this->lng);
1177 
1178  return $toolbar;
1179  }
1180 
1181  protected function outCorrectSolutionCmd()
1182  {
1183  $this->outCorrectSolution(); // cannot be named xxxCmd, because it's also called from context without Cmd in names
1184  }
1185 
1191  protected function outCorrectSolution()
1192  {
1193  if (!$this->object->getShowSolutionDetails()) {
1194  ilUtil::sendInfo($this->lng->txt("no_permission"), true);
1195  $this->ctrl->redirectByClass("ilobjtestgui", "infoScreen");
1196  }
1197 
1198  $testSession = $this->testSessionFactory->getSession();
1199  $activeId = $testSession->getActiveId();
1200 
1201  if (!($activeId > 0)) {
1202  $this->ctrl->redirectByClass("ilobjtestgui", "infoScreen");
1203  }
1204 
1205  $this->ctrl->saveParameter($this, "pass");
1206  $pass = (int) $_GET['pass'];
1207 
1208  $questionId = (int) $_GET['evaluation'];
1209 
1210  $testSequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($activeId, $pass);
1211  $testSequence->loadFromDb();
1212  $testSequence->loadQuestions();
1213 
1214  if (!$testSequence->questionExists($questionId)) {
1216  }
1217 
1218  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
1219  $testSequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($activeId, $pass);
1220  $testSequence->loadFromDb();
1221  $testSequence->loadQuestions();
1222 
1223  require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
1224  $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($testSession);
1225  $objectivesList = $this->buildQuestionRelatedObjectivesList($objectivesAdapter, $testSequence);
1226  $objectivesList->loadObjectivesTitles();
1227  } else {
1228  $objectivesList = null;
1229  }
1230 
1231  global $DIC;
1232  $ilTabs = $DIC['ilTabs'];
1233 
1234  if ($this instanceof ilTestEvalObjectiveOrientedGUI) {
1235  $ilTabs->setBackTarget(
1236  $this->lng->txt("tst_back_to_virtual_pass"),
1237  $this->ctrl->getLinkTarget($this, 'showVirtualPass')
1238  );
1239  } else {
1240  $ilTabs->setBackTarget(
1241  $this->lng->txt("tst_back_to_pass_details"),
1242  $this->ctrl->getLinkTarget($this, 'outUserPassDetails')
1243  );
1244  }
1245  $ilTabs->clearSubTabs();
1246 
1247  include_once("./Services/Style/Content/classes/class.ilObjStyleSheet.php");
1248  $this->tpl->setCurrentBlock("ContentStyle");
1249  $this->tpl->setVariable("LOCATION_CONTENT_STYLESHEET", ilObjStyleSheet::getContentStylePath(0));
1250  $this->tpl->parseCurrentBlock();
1251 
1252  $this->tpl->setCurrentBlock("SyntaxStyle");
1253  $this->tpl->setVariable("LOCATION_SYNTAX_STYLESHEET", ilObjStyleSheet::getSyntaxStylePath());
1254  $this->tpl->parseCurrentBlock();
1255 
1256  $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css", "Modules/Test"), "print");
1257  if ($this->object->getShowSolutionAnswersOnly()) {
1258  $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print_hide_content.css", "Modules/Test"), "print");
1259  }
1260 
1261  $solution = $this->getCorrectSolutionOutput($questionId, $activeId, $pass, $objectivesList);
1262 
1263  $this->tpl->setContent($solution);
1264  }
1265 
1270  public function populatePassFinishDate($tpl, $passFinishDate)
1271  {
1274  $passFinishDate = ilDatePresentation::formatDate(new ilDateTime($passFinishDate, IL_CAL_UNIX));
1276  $tpl->setVariable("PASS_FINISH_DATE_LABEL", $this->lng->txt('tst_pass_finished_on'));
1277  $tpl->setVariable("PASS_FINISH_DATE_VALUE", $passFinishDate);
1278  }
1279 
1285  public function populateExamId(ilTemplate $tpl, int $activeId, int $pass)
1286  {
1287  if ($this->object->isShowExamIdInTestResultsEnabled()) {
1288  $tpl->setVariable("EXAM_ID_TXT", $this->lng->txt('exam_id'));
1289  $tpl->setVariable('EXAM_ID', ilObjTest::lookupExamId(
1290  $activeId,
1291  $pass
1292  ));
1293  }
1294  }
1295 }
1296 
1297 // internal sort function to sort the result array
1298 function sortResults($a, $b)
1299 {
1300  $sort = ($_GET["sort"]) ? ($_GET["sort"]) : "nr";
1301  $sortorder = ($_GET["sortorder"]) ? ($_GET["sortorder"]) : "asc";
1302  if (strcmp($sortorder, "asc")) {
1303  $smaller = 1;
1304  $greater = -1;
1305  } else {
1306  $smaller = -1;
1307  $greater = 1;
1308  }
1309  if ($a[$sort] == $b[$sort]) {
1310  return 0;
1311  }
1312  return ($a[$sort] < $b[$sort]) ? $smaller : $greater;
1313 }
static getContentStylePath($a_style_id, $add_random=true, $add_token=true)
get content style path
static _lookupLogin($a_user_id)
lookup login
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms public
getFilteredTestResult($active_id, $pass, $considerHiddenQuestions, $considerOptionalQuestions)
getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, $overwrite_anonymity=false)
Returns the user data for a test results output.
setContextResultPresentation($contextResultPresentation)
$data
Definition: storeScorm.php:23
$_SESSION["AccountId"]
static getStyleSheetLocation($mode="output", $a_css_name="", $a_css_location="")
get full style sheet file name (path inclusive) of current user
$_GET["client_id"]
const PDF_USER_RESULT
PDF Purposes.
buildFixedShufflerSeedFromBasicSeed(string $basic_seed)
sortResults($a, $b)
static setUseRelativeDates($a_status)
set use relative dates
getResultsSignature()
Returns HTML code for a signature field.
const IL_CAL_UNIX
static accessViolationRedirect()
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false, $include_seconds=false)
Format a date public.
static getRequestRequestStatisticDataRegisterByActiveId($activeId)
static useRelativeDates()
check if relative dates are used
getCorrectSolutionOutput($question_id, $active_id, $pass, ilTestQuestionRelatedObjectivesList $objectivesList=null)
Returns an output of the solution to an answer compared to the correct solution.
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
buildQuestionRelatedObjectivesList(ilLOTestQuestionAdapter $objectivesAdapter, ilTestQuestionSequence $testSequence)
static getInstance(ilTestSession $a_test_session)
getResultsHeadUserAndPass($active_id, $pass)
Returns the user and pass data for a test results output.
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:615
getPassDetailsOverviewTableGUI($result_array, $active_id, $pass, $targetGUI, $targetCMD, $questionDetailsCMD, $questionAnchorNav, ilTestQuestionRelatedObjectivesList $objectivesList=null, $multipleObjectivesInvolved=true)
Class for single dates.
buildPassOverviewTableGUI($targetGUI)
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
getCommand($cmd)
Retrieves the ilCtrl command.
buildQuestionRelatedObjectiveList(ilTestQuestionSequence $a_test_sequence, ilTestQuestionRelatedObjectivesList $a_objectives_list)
setParticipantData($participantData)
global $DIC
Definition: goto.php:24
outCorrectSolution()
Creates an output of the solution of an answer compared to the correct solution.
redirection script todo: (a better solution should control the processing via a xml file) ...
Class ilTestPassOverviewTableGUI.
static initDomEvent(ilGlobalTemplateInterface $a_main_tpl=null)
Init YUI DomEvent.
static getSyntaxStylePath()
get syntax style path
static lookupLastTestPassAccess($activeId, $passIndex)
getResultsOfUserOutput($testSession, $active_id, $pass, $targetGUI, $show_pass_details=true, $show_answers=true, $show_question_only=false, $show_reached_points=false)
Output of the pass overview for a test called by a test participant.
Service class for tests.
buildPassDetailsOverviewTableGUI($targetGUI, $targetCMD)
static _getManualScoring()
Retrieve the manual scoring settings.
__construct(ilObjTest $a_object)
The constructor takes the test object reference as parameter.
global $ilDB
populatePassFinishDate($tpl, $passFinishDate)
$ret
Definition: parser.php:6
populateExamId(ilTemplate $tpl, int $activeId, int $pass)
executeCommand()
execute command
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
setObjectiveOrientedContainer(ilTestObjectiveOrientedContainer $objectiveOrientedContainer)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static generatePDF($pdf_output, $output_mode, $filename=null, $purpose=null)
$ilUser
Definition: imgupload.php:18
static _getReachedPoints($active_id, $question_id, $pass=null)
Returns the points, a learner has reached answering the question.
getPassListOfAnswers(&$result_array, $active_id, $pass, $show_solutions=false, $only_answered_questions=false, $show_question_only=false, $show_reached_points=false, $anchorNav=false, ilTestQuestionRelatedObjectivesList $objectivesList=null, ilTestResultHeaderLabelBuilder $testResultHeaderLabelBuilder=null)
Returns the list of answers of a users test pass.
getPassListOfAnswersWithScoring(&$result_array, $active_id, $pass, $show_solutions=false)
Returns the list of answers of a users test pass and offers a scoring option.
buildQuestionAnswerShuffler(string $question_id, string $active_id, string $active_pass)
static prepareGenerationRequest($service, $purpose)
Prepare the content processing for a PDF generation request This function should be called as in a re...
getPassOverviewTableData(ilTestSession $testSession, $passes, $withResults)
getQuestionResultForTestUsers($question_id, $test_id)
Creates a HTML representation for the results of a given question in a test.
$i
Definition: metadata.php:24
static lookupExamId($active_id, $pass)