ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilTestServiceGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
30 use ILIAS\Style\Content\Service as ContentStyle;
31 
32 require_once "./Modules/Test/classes/inc.AssessmentConstants.php";
33 
49 {
51  protected \ILIAS\TestQuestionPool\QuestionInfoService $questioninfo;
52  protected ?ilTestService $service = null;
53  protected ilDBInterface $db;
54  protected ilLanguage $lng;
56  protected ilHelpGUI $help;
58 
65  protected ContentStyle $content_style;
67  protected ilAccess $access;
68  protected HTTPServices $http;
69  protected ilCtrl $ctrl;
71  protected ilTabsGUI $tabs;
74  protected ilObjUser $user;
77  protected Refinery $refinery;
84 
85  protected ILIAS $ilias;
86  protected ilSetting $settings;
88  protected ilTree $tree;
89  protected int $ref_id;
90 
94 
96 
98 
99  private bool $contextResultPresentation = true;
100 
101  public function isContextResultPresentation(): bool
102  {
104  }
105 
106  public function setContextResultPresentation(bool $contextResultPresentation)
107  {
108  $this->contextResultPresentation = $contextResultPresentation;
109  }
110 
117  public function __construct(
118  protected ilObjTest $object
119  ) {
121  global $DIC;
122  $this->lng = $DIC['lng'];
123  $this->tpl = $DIC['tpl'];
124  $this->content_style = $DIC->contentStyle();
125  $this->error = $DIC['ilErr'];
126  $this->access = $DIC['ilAccess'];
127  $this->http = $DIC['http'];
128  $this->ctrl = $DIC['ilCtrl'];
129  $this->user = $DIC->user();
130  $this->ilias = $DIC['ilias'];
131  $this->settings = $DIC['ilSetting'];
132  $this->global_screen = $DIC['global_screen'];
133  $this->tree = $DIC['tree'];
134  $this->db = $DIC['ilDB'];
135  $this->component_repository = $DIC['component.repository'];
136  $this->navigation_history = $DIC['ilNavigationHistory'];
137  $this->tabs = $DIC['ilTabs'];
138  $this->toolbar = $DIC['ilToolbar'];
139  $this->logging_services = $DIC->logger();
140  $this->help = $DIC['ilHelp'];
141  $this->refinery = $DIC->refinery();
142  $this->ui_factory = $DIC['ui.factory'];
143  $this->ui_renderer = $DIC['ui.renderer'];
144  $this->rbac_system = $DIC['rbacsystem'];
145  $this->obj_cache = $DIC['ilObjDataCache'];
146  $this->skills_service = $DIC->skills();
147  $this->post_wrapper = $DIC->http()->wrapper()->post();
148 
149  $this->questioninfo = $DIC->testQuestionPool()->questionInfo();
150  $this->service = new ilTestService($this->object, $this->db, $this->questioninfo);
151 
152  $this->lng->loadLanguageModule('cert');
153  $this->ref_id = $this->object->getRefId();
154  $this->testSessionFactory = new ilTestSessionFactory($this->object, $this->db, $this->user);
155  $this->testSequenceFactory = new ilTestSequenceFactory($this->object, $this->db, $this->questioninfo);
156  $this->objective_oriented_container = null;
157 
158  $this->ui_factory = $DIC['ui.factory'];
159  $this->ui_renderer = $DIC['ui.renderer'];
160 
161  $local_dic = $object->getLocalDIC();
162  $this->testrequest = $local_dic['request.internal'];
163  $this->participant_access_filter = $local_dic['participantAccessFilterFactory'];
164  $this->shuffler = $local_dic['shuffler'];
165  $this->results_factory = $local_dic['factory.results'];
166  $this->results_presentation_factory = $local_dic['factory.results_presentation'];
167  }
168 
169  public function setParticipantData(ilTestParticipantData $participantData): void
170  {
171  $this->participantData = $participantData;
172  }
173 
175  {
176  return $this->participantData;
177  }
178 
187  public function getPassOverviewTableData(ilTestSession $testSession, $passes, $withResults): array
188  {
189  $data = [];
190 
191  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
192  $considerHiddenQuestions = false;
193 
194  $objectives_adapter = ilLOTestQuestionAdapter::getInstance($testSession);
195  } else {
196  $considerHiddenQuestions = true;
197  }
198 
199  $scoredPass = $this->object->_getResultPass($testSession->getActiveId());
200 
202  $testSession->getActiveId()
203  );
204 
205  foreach ($passes as $pass) {
206  $row = [
207  'scored' => false,
208  'pass' => $pass,
209  'date' => ilObjTest::lookupLastTestPassAccess($testSession->getActiveId(), $pass)
210  ];
211  $considerOptionalQuestions = true;
212 
213  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
214  $test_sequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($testSession->getActiveId(), $pass);
215  $test_sequence->loadFromDb();
216  $test_sequence->loadQuestions();
217 
218  if ($this->object->isRandomTest() && !$test_sequence->isAnsweringOptionalQuestionsConfirmed()) {
219  $considerOptionalQuestions = false;
220  }
221 
222  $test_sequence->setConsiderHiddenQuestionsEnabled($considerHiddenQuestions);
223  $test_sequence->setConsiderOptionalQuestionsEnabled($considerOptionalQuestions);
224 
225  $objectives_list = $this->buildQuestionRelatedObjectivesList($objectives_adapter, $test_sequence);
226  $objectives_list->loadObjectivesTitles();
227 
228  $row['objectives'] = $objectives_list->getUniqueObjectivesStringForQuestions($test_sequence->getUserSequenceQuestions());
229  }
230 
231  if ($withResults) {
232  $result_array = $this->object->getTestResult($testSession->getActiveId(), $pass, false, $considerHiddenQuestions, $considerOptionalQuestions);
233 
234  foreach ($result_array as $resultStructKEY => $question) {
235  if ($resultStructKEY === 'test' || $resultStructKEY === 'pass') {
236  continue;
237  }
238 
239  $requestData = $questionHintRequestRegister->getRequestByTestPassIndexAndQuestionId($pass, $question['qid']);
240 
241  if ($requestData instanceof ilAssQuestionHintRequestStatisticData && $result_array[$resultStructKEY]['requested_hints'] === null) {
242  $result_array['pass']['total_requested_hints'] += $requestData->getRequestsCount();
243 
244  $result_array[$resultStructKEY]['requested_hints'] = $requestData->getRequestsCount();
245  $result_array[$resultStructKEY]['hint_points'] = $requestData->getRequestsPoints();
246  }
247  }
248 
249  if (!$result_array['pass']['total_max_points']) {
250  $row['percentage'] = 0;
251  } else {
252  $row['percentage'] = ($result_array['pass']['total_reached_points'] / $result_array['pass']['total_max_points']) * 100;
253  }
254 
255  $row['max_points'] = $result_array['pass']['total_max_points'];
256  $row['reached_points'] = $result_array['pass']['total_reached_points'];
257  $row['scored'] = ($pass == $scoredPass);
258  $row['num_workedthrough_questions'] = $result_array['pass']['num_workedthrough'];
259  $row['num_questions_total'] = $result_array['pass']['num_questions_total'];
260 
261  if ($this->object->isOfferingQuestionHintsEnabled()) {
262  $row['hints'] = $result_array['pass']['total_requested_hints'];
263  }
264  }
265 
266  $data[] = $row;
267  }
268 
269  return $data;
270  }
271 
275  public function setObjectiveOrientedContainer(ilTestObjectiveOrientedContainer $objective_oriented_container)
276  {
277  $this->objective_oriented_container = $objective_oriented_container;
278  }
279 
284  {
286  }
287 
291  public function executeCommand()
292  {
293  $cmd = $this->ctrl->getCmd();
294  $next_class = $this->ctrl->getNextClass($this);
295 
296  $cmd = $this->getCommand($cmd);
297  switch ($next_class) {
298  default:
299  $ret = &$this->$cmd();
300  break;
301  }
302  return $ret;
303  }
304 
310  public function getCommand($cmd)
311  {
312  return $cmd;
313  }
314 
316  {
317  $table = new ilTestPassOverviewTableGUI($target_gui, '');
318 
319  $table->setPdfPresentationEnabled(
320  $this->testrequest->isset('pdf') && $this->testrequest->raw('pdf') == 1
321  );
322 
323  $table->setObjectiveOrientedPresentationEnabled(
324  $this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()
325  );
326 
327  return $table;
328  }
329 
340  public function getPassListOfAnswers(
341  &$result_array,
342  $active_id,
343  $pass,
344  $show_solutions = false,
345  $only_answered_questions = false,
346  $show_question_only = false,
347  $show_reached_points = false,
348  $anchorNav = false,
349  ilTestQuestionRelatedObjectivesList $objectives_list = null,
350  ilTestResultHeaderLabelBuilder $testResultHeaderLabelBuilder = null
351  ): string {
352  $maintemplate = new ilTemplate("tpl.il_as_tst_list_of_answers.html", true, true, "Modules/Test");
353 
354  $counter = 1;
355  // output of questions with solutions
356  foreach ($result_array as $question_data) {
357  if (!array_key_exists('workedthrough', $question_data)) {
358  $question_data['workedthrough'] = 0;
359  }
360  if (!array_key_exists('qid', $question_data)) {
361  $question_data['qid'] = -1;
362  }
363 
364  if (($question_data["workedthrough"] == 1) || ($only_answered_questions == false)) {
365  $template = new ilTemplate("tpl.il_as_qpl_question_printview.html", true, true, "Modules/TestQuestionPool");
366  $question_id = $question_data["qid"] ?? null;
367  if ($question_id !== null
368  && $question_id !== -1
369  && is_numeric($question_id)) {
370  $maintemplate->setCurrentBlock("printview_question");
371  $question_gui = $this->object->createQuestionGUI("", $question_id);
372 
373  $question_gui->object->setShuffler($this->shuffler->getAnswerShuffleFor(
374  (int) $question_id,
375  (int) $active_id,
376  (int) $pass
377  ));
378  if (is_object($question_gui)) {
379  if ($anchorNav) {
380  $template->setCurrentBlock('block_id');
381  $template->setVariable('BLOCK_ID', "detailed_answer_block_act_{$active_id}_qst_{$question_id}");
382  $template->parseCurrentBlock();
383 
384  $template->setCurrentBlock('back_anchor');
385  $template->setVariable('HREF_BACK_ANCHOR', "#pass_details_tbl_row_act_{$active_id}_qst_{$question_id}");
386  $template->setVariable('TXT_BACK_ANCHOR', $this->lng->txt('tst_back_to_question_list'));
387  $template->parseCurrentBlock();
388  }
389 
390  if ($show_reached_points) {
391  $template->setCurrentBlock("result_points");
392  $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());
393  $template->parseCurrentBlock();
394  }
395  $template->setVariable("COUNTER_QUESTION", $counter . ". ");
396  $template->setVariable("TXT_QUESTION_ID", $this->lng->txt('question_id_short'));
397  $template->setVariable("QUESTION_ID", $question_gui->object->getId());
398  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitleForHTMLOutput()));
399 
400  if ($objectives_list !== null) {
401  $objectives = $this->lng->txt('tst_res_lo_objectives_header') . ': ';
402  $objectives .= $objectives_list->getQuestionRelatedObjectiveTitles($question_gui->object->getId());
403  $template->setVariable("OBJECTIVES", $objectives);
404  }
405 
406  $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? true : false;
407 
408  $show_feedback = $this->isContextResultPresentation() && $this->object->getShowSolutionFeedback();
409  $show_best_solution = $this->isContextResultPresentation() && $show_solutions;
410  $show_graphical_output = $this->isContextResultPresentation();
411 
412  if ($show_best_solution) {
413  $compare_template = new ilTemplate('tpl.il_as_tst_answers_compare.html', true, true, 'Modules/Test');
414  $test_session = $this->testSessionFactory->getSession($active_id);
415  if ($pass <= $test_session->getLastFinishedPass()) {
416  $compare_template->setVariable("HEADER_PARTICIPANT", $this->lng->txt('tst_header_participant'));
417  } else {
418  $compare_template->setVariable("HEADER_PARTICIPANT", $this->lng->txt('tst_header_participant_no_answer'));
419  }
420 
421  $compare_template->setVariable("HEADER_SOLUTION", $this->lng->txt('tst_header_solution'));
422  $result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_graphical_output, false, $show_question_only, $show_feedback);
423  $best_output = $question_gui->getSolutionOutput($active_id, $pass, false, false, $show_question_only, false, true);
424 
425  $compare_template->setVariable('PARTICIPANT', $result_output);
426  $compare_template->setVariable('SOLUTION', $best_output);
427  $template->setVariable('SOLUTION_OUTPUT', $compare_template->get());
428  } else {
429  $result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_graphical_output, false, $show_question_only, $show_feedback);
430  $template->setVariable('SOLUTION_OUTPUT', $result_output);
431  }
432 
433  $maintemplate->setCurrentBlock("printview_question");
434  $maintemplate->setVariable("QUESTION_PRINTVIEW", $template->get());
435  $maintemplate->parseCurrentBlock();
436  $counter++;
437  }
438  }
439  }
440  }
441 
442  if ($testResultHeaderLabelBuilder !== null) {
443  if ($pass !== null) {
444  $headerText = $testResultHeaderLabelBuilder->getListOfAnswersHeaderLabel($pass + 1);
445  } else {
446  $headerText = $testResultHeaderLabelBuilder->getVirtualListOfAnswersHeaderLabel();
447  }
448  } else {
449  $headerText = '';
450  }
451 
452  $maintemplate->setVariable("RESULTS_OVERVIEW", $headerText);
453  return $maintemplate->get();
454  }
455 
468  public function getPassListOfAnswersWithScoring(&$result_array, $active_id, $pass, $show_solutions = false): string
469  {
470  $maintemplate = new ilTemplate("tpl.il_as_tst_list_of_answers.html", true, true, "Modules/Test");
472 
473  $counter = 1;
474  // output of questions with solutions
475  foreach ($result_array as $question_data) {
476  $question = $question_data["qid"];
477  if (is_numeric($question)) {
478  $question_gui = $this->object->createQuestionGUI("", $question);
479  if (in_array($question_gui->object->getQuestionTypeID(), $scoring)) {
480  $template = new ilTemplate("tpl.il_as_qpl_question_printview.html", true, true, "Modules/TestQuestionPool");
481  $scoretemplate = new ilTemplate("tpl.il_as_tst_manual_scoring_points.html", true, true, "Modules/Test");
482  #mbecker: No such block. $this->tpl->setCurrentBlock("printview_question");
483  $template->setVariable("COUNTER_QUESTION", $counter . ". ");
484  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitleForHTMLOutput()));
485  $points = $question_gui->object->getMaximumPoints();
486  if ($points == 1) {
487  $template->setVariable("QUESTION_POINTS", $points . " " . $this->lng->txt("point"));
488  } else {
489  $template->setVariable("QUESTION_POINTS", $points . " " . $this->lng->txt("points"));
490  }
491 
492  $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? true : false;
493  $result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_solutions, false, $show_question_only, $this->object->getShowSolutionFeedback(), false, true);
494 
495  $solout = $question_gui->object->getSuggestedSolutionOutput();
496  if (strlen($solout)) {
497  $scoretemplate->setCurrentBlock("suggested_solution");
498  $scoretemplate->setVariable("TEXT_SUGGESTED_SOLUTION", $this->lng->txt("solution_hint"));
499  $scoretemplate->setVariable("VALUE_SUGGESTED_SOLUTION", $solout);
500  $scoretemplate->parseCurrentBlock();
501  }
502 
503  $scoretemplate->setCurrentBlock("feedback");
504  $scoretemplate->setVariable("FEEDBACK_NAME_INPUT", $question);
505  $feedback = ilObjTest::getSingleManualFeedback((int) $active_id, (int) $question, (int) $pass)['feedback'] ?? '';
506  $scoretemplate->setVariable(
507  "VALUE_FEEDBACK",
509  $this->object->prepareTextareaOutput($feedback, true)
510  )
511  );
512  $scoretemplate->setVariable("TEXT_MANUAL_FEEDBACK", $this->lng->txt("set_manual_feedback"));
513  $scoretemplate->parseCurrentBlock();
514 
515  $scoretemplate->setVariable("NAME_INPUT", $question);
516  $this->ctrl->setParameter($this, "active_id", $active_id);
517  $this->ctrl->setParameter($this, "pass", $pass);
518  $scoretemplate->setVariable("FORMACTION", $this->ctrl->getFormAction($this, "manscoring"));
519  $scoretemplate->setVariable("LABEL_INPUT", $this->lng->txt("tst_change_points_for_question"));
520  $scoretemplate->setVariable("VALUE_INPUT", " value=\"" . assQuestion::_getReachedPoints($active_id, $question_data["qid"], $pass) . "\"");
521  $scoretemplate->setVariable("VALUE_SAVE", $this->lng->txt("save"));
522 
523  $template->setVariable("SOLUTION_OUTPUT", $result_output);
524  $maintemplate->setCurrentBlock("printview_question");
525  $maintemplate->setVariable("QUESTION_PRINTVIEW", $template->get());
526  $maintemplate->setVariable("QUESTION_SCORING", $scoretemplate->get());
527  $maintemplate->parseCurrentBlock();
528  }
529  $counter++;
530  }
531  }
532  if ($counter == 1) {
533  // no scorable questions found
534  $maintemplate->setVariable("NO_QUESTIONS_FOUND", $this->lng->txt("manscoring_questions_not_found"));
535  }
536  $maintemplate->setVariable("RESULTS_OVERVIEW", sprintf($this->lng->txt("manscoring_results_pass"), $pass + 1));
537 
539 
540  return $maintemplate->get();
541  }
542 
543  protected function getPassDetailsOverviewTableGUI(
544  array $result_array,
545  int $active_id,
546  int $pass,
548  string $target_cmd,
549  ilTestQuestionRelatedObjectivesList $objectives_list = null,
550  bool $multiple_objectives_involved = true
552  $this->ctrl->setParameter($target_gui, 'active_id', $active_id);
553  $this->ctrl->setParameter($target_gui, 'pass', $pass);
554 
555  $table_gui = $this->buildPassDetailsOverviewTableGUI($target_gui, $target_cmd);
556  $table_gui->setShowHintCount($this->object->isOfferingQuestionHintsEnabled());
557 
558  if ($objectives_list !== null) {
559  $table_gui->setQuestionRelatedObjectivesList($objectives_list);
560  $table_gui->setObjectiveOrientedPresentationEnabled(true);
561  }
562 
563  $table_gui->setMultipleObjectivesInvolved($multiple_objectives_involved);
564 
565  $table_gui->setActiveId($active_id);
566  $table_gui->setShowSuggestedSolution(false);
567 
568  $users_question_solutions = [];
569 
570  foreach ($result_array as $key => $val) {
571  if ($key === 'test' || $key === 'pass') {
572  continue;
573  }
574 
575  if ($this->object->getShowSolutionSuggested() && strlen($val['solution'])) {
576  $table_gui->setShowSuggestedSolution(true);
577  }
578 
579  if (isset($val['pass'])) {
580  $table_gui->setPassColumnEnabled(true);
581  }
582 
583  $users_question_solutions[$key] = $val;
584  }
585 
586  $table_gui->initColumns();
587 
588  $table_gui->setFilterCommand($target_cmd . 'SetTableFilter');
589  $table_gui->setResetCommand($target_cmd . 'ResetTableFilter');
590 
591  $table_gui->setData($users_question_solutions);
592 
593  return $table_gui;
594  }
595 
602  public function getResultsSignature(): string
603  {
604  if ($this->object->getShowSolutionSignature() && !$this->object->getAnonymity()) {
605  $template = new ilTemplate("tpl.il_as_tst_results_userdata_signature.html", true, true, "Modules/Test");
606  $template->setVariable("TXT_DATE", $this->lng->txt("date"));
609  $template->setVariable("VALUE_DATE", ilDatePresentation::formatDate(new ilDate(time(), IL_CAL_UNIX)));
611  $template->setVariable("TXT_SIGNATURE", $this->lng->txt("tst_signature"));
612  $template->setVariable("IMG_SPACER", ilUtil::getImagePath("media/spacer.png"));
613  return $template->get();
614  } else {
615  return "";
616  }
617  }
618 
628  public function getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, $overwrite_anonymity = false): string
629  {
630  if (!is_object($testSession)) {
631  throw new InvalidArgumentException('Not an object, expected ilTestSession');
632  }
633  $template = new ilTemplate("tpl.il_as_tst_results_userdata.html", true, true, "Modules/Test");
634  $user_id = $this->object->_getUserIdFromActiveId($active_id);
635  if (strlen(ilObjUser::_lookupLogin($user_id)) > 0) {
636  $user = new ilObjUser($user_id);
637  } else {
638  $user = new ilObjUser();
639  $user->setLastname($this->lng->txt("deleted_user"));
640  }
641  $t = $testSession->getSubmittedTimestamp();
642  if (!$t) {
643  $t = $this->object->_getLastAccess($testSession->getActiveId());
644  }
645 
646  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
647  $uname = $this->object->userLookupFullName($user_id, $overwrite_anonymity);
648  $template->setCurrentBlock("name");
649  $template->setVariable('TXT_USR_NAME', $this->lng->txt("name"));
650  $template->setVariable('VALUE_USR_NAME', $uname);
651  $template->parseCurrentBlock();
652  }
653 
654  $title_matric = "";
655  if (strlen($user->getMatriculation()) && (($this->object->getAnonymity() == false) || ($overwrite_anonymity))) {
656  $template->setCurrentBlock("matriculation");
657  $template->setVariable("TXT_USR_MATRIC", $this->lng->txt("matriculation"));
658  $template->setVariable("VALUE_USR_MATRIC", $user->getMatriculation());
659  $template->parseCurrentBlock();
660  $title_matric = " - " . $this->lng->txt("matriculation") . ": " . $user->getMatriculation();
661  }
662 
663  $invited_user = array_pop($this->object->getInvitedUsers($user_id));
664  $title_client = '';
665  if (is_array($invited_user)
666  && array_key_exists('clientip', $invited_user)
667  && is_string($invited_user['clientip'])
668  && trim($invited_user['clientip']) !== ''
669  ) {
670  $template->setCurrentBlock("client_ip");
671  $template->setVariable("TXT_CLIENT_IP", $this->lng->txt("client_ip"));
672  $template->setVariable("VALUE_CLIENT_IP", $invited_user["clientip"]);
673  $template->parseCurrentBlock();
674  $title_client = " - " . $this->lng->txt("clientip") . ": " . $invited_user["clientip"];
675  }
676 
677  $template->setVariable("TXT_TEST_TITLE", $this->lng->txt("title"));
678  $template->setVariable("VALUE_TEST_TITLE", $this->object->getTitle());
679 
680  // change the pagetitle (tab title or title in title bar of window)
681  $pagetitle = $this->object->getTitle() . $title_matric . $title_client;
682  $this->tpl->setHeaderPageTitle($pagetitle);
683 
684  return $template->get();
685  }
686 
696  public function getCorrectSolutionOutput($question_id, $active_id, $pass, ilTestQuestionRelatedObjectivesList $objectives_list = null): string
697  {
698  $ilUser = $this->user;
699 
700  $test_id = $this->object->getTestId();
701  $question_gui = $this->object->createQuestionGUI("", $question_id);
702 
703  $template = new ilTemplate("tpl.il_as_tst_correct_solution_output.html", true, true, "Modules/Test");
704  $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? true : false;
705  $result_output = $question_gui->getSolutionOutput($active_id, $pass, true, false, $show_question_only, $this->object->getShowSolutionFeedback(), false, false, true);
706  $best_output = $question_gui->getSolutionOutput($active_id, $pass, false, false, $show_question_only, false, true, false, false);
707  if ($this->object->getShowSolutionFeedback() && $this->testrequest->raw('cmd') != 'outCorrectSolution') {
708  $specificAnswerFeedback = $question_gui->getSpecificFeedbackOutput(
709  $question_gui->object->fetchIndexedValuesFromValuePairs(
710  $question_gui->object->getSolutionValues($active_id, $pass)
711  )
712  );
713  if (strlen($specificAnswerFeedback)) {
714  $template->setCurrentBlock("outline_specific_feedback");
715  $template->setVariable("OUTLINE_SPECIFIC_FEEDBACK", $specificAnswerFeedback);
716  $template->parseCurrentBlock();
717  }
718  }
719  $template->setVariable("TEXT_YOUR_SOLUTION", $this->lng->txt("tst_your_answer_was"));
720  $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
721  // I set both old and new since the old one is set as well in several places.
722  $maxpoints = $question_gui->object->getMaximumPoints();
723  if ($maxpoints == 1) {
724  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitleForHTMLOutput()) . " (" . $maxpoints . " " . $this->lng->txt("point") . ")");
725  } else {
726  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitleForHTMLOutput()) . " (" . $maxpoints . " " . $this->lng->txt("points") . ")");
727  }
728  if ($objectives_list !== null) {
729  $objectives = $this->lng->txt('tst_res_lo_objectives_header') . ': ';
730  $objectives .= $objectives_list->getQuestionRelatedObjectiveTitles($question_gui->object->getId());
731  $template->setVariable('OBJECTIVES', $objectives);
732  }
733  $template->setVariable("SOLUTION_OUTPUT", $result_output);
734  $template->setVariable("RECEIVED_POINTS", sprintf($this->lng->txt("you_received_a_of_b_points"), $question_gui->object->getReachedPoints($active_id, $pass), $maxpoints));
735  $template->setVariable("FORMACTION", $this->ctrl->getFormAction($this));
736  $template->setVariable("BACKLINK_TEXT", "&lt;&lt; " . $this->lng->txt("back"));
737  return $template->get();
738  }
739 
752  public function getResultsOfUserOutput(
753  ilTestSession $testSession,
754  int $active_id,
755  int $pass,
756  ilParticipantsTestResultsGUI $target_gui,
757  bool $show_pass_details = true,
758  bool $show_answers = true,
759  bool $show_question_only = false,
760  bool $show_reached_points = false
761  ): string {
762  $template = new ilTemplate("tpl.il_as_tst_results_participant.html", true, true, "Modules/Test");
763 
764  if ($this->participantData instanceof ilTestParticipantData) {
765  $user_id = $this->participantData->getUserIdByActiveId($active_id);
766  $uname = $this->participantData->getConcatedFullnameByActiveId($active_id, false);
767  } else {
768  $user_id = $this->object->_getUserIdFromActiveId($active_id);
769  $uname = $this->object->userLookupFullName($user_id, true);
770  }
771 
772  if ($this->object->getAnonymity()) {
773  $uname = $this->lng->txt('anonymous');
774  }
775 
776  if ((($this->testrequest->isset('pass')) && (strlen($this->testrequest->raw("pass")) > 0)) || (!is_null($pass))) {
777  if (is_null($pass)) {
778  $pass = $this->testrequest->raw("pass");
779  }
780  }
781 
782  if (!is_null($pass)) {
783  $testResultHeaderLabelBuilder = new ilTestResultHeaderLabelBuilder($this->lng, $this->obj_cache);
784  $objectives_list = null;
785 
786  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
787  $test_sequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($active_id, $pass);
788  $test_sequence->loadFromDb();
789  $test_sequence->loadQuestions();
790 
791  $objectives_adapter = ilLOTestQuestionAdapter::getInstance($testSession);
792 
793  $objectives_list = $this->buildQuestionRelatedObjectivesList($objectives_adapter, $test_sequence);
794  $objectives_list->loadObjectivesTitles();
795 
796  $testResultHeaderLabelBuilder->setObjectiveOrientedContainerId($testSession->getObjectiveOrientedContainerId());
797  $testResultHeaderLabelBuilder->setUserId($testSession->getUserId());
798  $testResultHeaderLabelBuilder->setTestObjId($this->object->getId());
799  $testResultHeaderLabelBuilder->setTestRefId($this->object->getRefId());
800  $testResultHeaderLabelBuilder->initObjectiveOrientedMode();
801  }
802 
803  $result_array = $this->object->getTestResult(
804  $active_id,
805  $pass,
806  false,
807  !$this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()
808  );
809 
810  $user_id = $this->object->_getUserIdFromActiveId($active_id);
811  $showAllAnswers = true;
812  if ($this->object->isExecutable($testSession, $user_id)) {
813  $showAllAnswers = false;
814  }
815  if ($show_answers) {
816  $list_of_answers = $this->getPassListOfAnswers(
817  $result_array,
818  $active_id,
819  $pass,
820  ilSession::get('tst_results_show_best_solutions'),
821  $showAllAnswers,
822  $show_question_only,
823  $show_reached_points,
824  $show_pass_details,
825  $objectives_list,
826  $testResultHeaderLabelBuilder
827  );
828  $template->setVariable("LIST_OF_ANSWERS", $list_of_answers);
829  }
830 
831  if ($show_pass_details) {
832  $overviewTableGUI = $this->getPassDetailsOverviewTableGUI(
833  $result_array,
834  $active_id,
835  $pass,
836  $target_gui,
837  "getResultsOfUserOutput",
838  $objectives_list
839  );
840  $overviewTableGUI->setTitle($testResultHeaderLabelBuilder->getPassDetailsHeaderLabel($pass + 1));
841  $template->setVariable("PASS_DETAILS", $overviewTableGUI->getHTML());
842  }
843 
844  $signature = $this->getResultsSignature();
845  $template->setVariable("SIGNATURE", $signature);
846 
847  if ($this->object->isShowExamIdInTestResultsEnabled()) {
848  $template->setCurrentBlock('exam_id_footer');
849  $template->setVariable('EXAM_ID_VAL', ilObjTest::lookupExamId(
850  $testSession->getActiveId(),
851  $pass
852  ));
853  $template->setVariable('EXAM_ID_TXT', $this->lng->txt('exam_id'));
854  $template->parseCurrentBlock();
855  }
856  }
857 
858  $template->setCurrentBlock('participant_back_anchor');
859  $template->setVariable("HREF_PARTICIPANT_BACK_ANCHOR", "#tst_results_toolbar");
860  $template->setVariable("TXT_PARTICIPANT_BACK_ANCHOR", $this->lng->txt('tst_back_to_top'));
861  $template->parseCurrentBlock();
862 
863  $template->setCurrentBlock('participant_block_id');
864  $template->setVariable("PARTICIPANT_BLOCK_ID", "participant_active_{$active_id}");
865  $template->parseCurrentBlock();
866 
867  if ($this->isGradingMessageRequired()) {
868  $gradingMessageBuilder = $this->getGradingMessageBuilder($active_id);
869  $gradingMessageBuilder->buildList();
870 
871  $template->setCurrentBlock('grading_message');
872  $template->setVariable('GRADING_MESSAGE', $gradingMessageBuilder->getList());
873  $template->parseCurrentBlock();
874  }
875 
876 
877  $user_data = $this->getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, true);
878  $template->setVariable("TEXT_HEADING", sprintf($this->lng->txt("tst_result_user_name"), $uname));
879  $template->setVariable("USER_DATA", $user_data);
880 
881  $this->populateExamId($template, (int) $active_id, (int) $pass);
882  $this->populatePassFinishDate($template, ilObjTest::lookupLastTestPassAccess($active_id, $pass));
883 
884  return $template->get();
885  }
886 
894  public function getResultsHeadUserAndPass($active_id, $pass): string
895  {
896  $template = new ilTemplate("tpl.il_as_tst_results_head_user_pass.html", true, true, "Modules/Test");
897  $user_id = $this->object->_getUserIdFromActiveId($active_id);
898  if (strlen(ilObjUser::_lookupLogin($user_id)) > 0) {
899  $user = new ilObjUser($user_id);
900  } else {
901  $user = new ilObjUser();
902  $user->setLastname($this->lng->txt("deleted_user"));
903  }
904  if (strlen($user->getMatriculation()) && (($this->object->getAnonymity() == false))) {
905  $template->setCurrentBlock("user_matric");
906  $template->setVariable("TXT_USR_MATRIC", $this->lng->txt("matriculation"));
907  $template->parseCurrentBlock();
908  $template->setCurrentBlock("user_matric_value");
909  $template->setVariable("VALUE_USR_MATRIC", $user->getMatriculation());
910  $template->parseCurrentBlock();
911  $template->touchBlock("user_matric_separator");
912  }
913 
914  $invited_user = array_pop($this->object->getInvitedUsers($user_id));
915  if (strlen($invited_user["clientip"] ?? '')) {
916  $template->setCurrentBlock("user_clientip");
917  $template->setVariable("TXT_CLIENT_IP", $this->lng->txt("client_ip"));
918  $template->parseCurrentBlock();
919  $template->setCurrentBlock("user_clientip_value");
920  $template->setVariable("VALUE_CLIENT_IP", $invited_user["clientip"]);
921  $template->parseCurrentBlock();
922  $template->touchBlock("user_clientip_separator");
923  }
924 
925  $template->setVariable("TXT_USR_NAME", $this->lng->txt("name"));
926  $uname = $this->object->userLookupFullName($user_id, false);
927  $template->setVariable("VALUE_USR_NAME", $uname);
928  $template->setVariable("TXT_PASS", $this->lng->txt("scored_pass"));
929  $template->setVariable("VALUE_PASS", $pass);
930  return $template->get();
931  }
932 
933  public function getQuestionResultForTestUsers(int $question_id, int $test_id): string
934  {
935  $question_gui = $this->object->createQuestionGUI("", $question_id);
936 
937  $this->object->setAccessFilteredParticipantList(
938  $this->object->buildStatisticsAccessFilteredParticipantList()
939  );
940 
941  $foundusers = $this->object->getParticipantsForTestAndQuestion($test_id, $question_id);
942  $output = '';
943  foreach ($foundusers as $active_id => $passes) {
944  $resultpass = $this->object->_getResultPass($active_id);
945  for ($i = 0; $i < count($passes); $i++) {
946  if (($resultpass !== null) && ($resultpass == $passes[$i]["pass"])) {
947  if ($output) {
948  $output .= "<br /><br /><br />";
949  }
950 
951  // check if re-instantiation is really neccessary
952  $question_gui = $this->object->createQuestionGUI("", $passes[$i]["qid"]);
953  $output .= $this->getResultsHeadUserAndPass($active_id, $resultpass + 1);
954  $question_gui->setRenderPurpose(assQuestionGUI::RENDER_PURPOSE_PRINT_PDF);
955  $output .= $question_gui->getSolutionOutput(
956  $active_id,
957  $resultpass,
958  $graphicalOutput = false,
959  $result_output = false,
960  $show_question_only = false,
961  $show_feedback = false
962  );
963  }
964  }
965  }
966  return $output;
967  }
968 
971  string $target_cmd
973  return new ilTestPassDetailsOverviewTableGUI($this->ctrl, $target_gui, $target_cmd);
974  }
975 
976  protected function isGradingMessageRequired(): bool
977  {
978  $session = $this->testSessionFactory->getSession();
979  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()
980  || $this->object->getScoreSettings()->getScoringSettings()->getPassScoring() === SCORE_LAST_PASS
981  && $session->getLastFinishedPass() < $session->getLastStartedPass()) {
982  return false;
983  }
984 
985  if ($this->object->isShowGradingStatusEnabled()
986  || $this->object->isShowGradingMarkEnabled()) {
987  return true;
988  }
989 
990  return false;
991  }
992 
993  protected function getGradingMessageBuilder(int $active_id): ilTestGradingMessageBuilder
994  {
995  $gradingMessageBuilder = new ilTestGradingMessageBuilder($this->lng, $this->tpl, $this->object);
996 
997  $gradingMessageBuilder->setActiveId($active_id);
998 
999  return $gradingMessageBuilder;
1000  }
1001 
1003  ilLOTestQuestionAdapter $objectives_adapter,
1004  ilTestQuestionSequence $test_sequence
1006  $questionRelatedObjectivesList = new ilTestQuestionRelatedObjectivesList();
1007 
1008  $objectives_adapter->buildQuestionRelatedObjectiveList($test_sequence, $questionRelatedObjectivesList);
1009 
1010  return $questionRelatedObjectivesList;
1011  }
1012 
1013  protected function getFilteredTestResult(
1014  int $active_id,
1015  int $pass,
1016  bool $considerHiddenQuestions,
1017  bool $considerOptionalQuestions
1018  ): array {
1019  $ilDB = $this->db;
1020  $component_repository = $this->component_repository;
1021 
1022  $table_gui = $this->buildPassDetailsOverviewTableGUI($this, 'outUserPassDetails');
1023 
1024  $questionList = new ilAssQuestionList($ilDB, $this->lng, $this->refinery, $component_repository);
1025 
1026  $questionList->setParentObjIdsFilter([$this->object->getId()]);
1027  $questionList->setQuestionInstanceTypeFilter(ilAssQuestionList::QUESTION_INSTANCE_TYPE_DUPLICATES);
1028 
1029  foreach ($table_gui->getFilterItems() as $item) {
1030  if (substr($item->getPostVar(), 0, strlen('tax_')) == 'tax_') {
1031  $v = $item->getValue();
1032 
1033  if (is_array($v) && count($v) && !(int) $v[0]) {
1034  continue;
1035  }
1036 
1037  $taxId = substr($item->getPostVar(), strlen('tax_'));
1038  $questionList->addTaxonomyFilter($taxId, $item->getValue(), $this->object->getId(), 'tst');
1039  } elseif ($item->getValue() !== false) {
1040  $questionList->addFieldFilter($item->getPostVar(), $item->getValue());
1041  }
1042  }
1043 
1044  $questionList->load();
1045 
1046  $filteredTestResult = [];
1047 
1048  $resultData = $this->object->getTestResult($active_id, $pass, false, $considerHiddenQuestions, $considerOptionalQuestions);
1049 
1050  foreach ($resultData as $resultItemKey => $resultItemValue) {
1051  if ($resultItemKey === 'test' || $resultItemKey === 'pass') {
1052  continue;
1053  }
1054 
1055  if (!$questionList->isInList($resultItemValue['qid'])) {
1056  continue;
1057  }
1058 
1059  $filteredTestResult[] = $resultItemValue;
1060  }
1061 
1062  return $filteredTestResult;
1063  }
1064 
1068  protected function populateContent($content)
1069  {
1070  $this->tpl->setContent($content);
1071  }
1072 
1077  {
1078  $toolbar = new ilTestResultsToolbarGUI($this->ctrl, $this->tpl, $this->lng);
1079 
1080  return $toolbar;
1081  }
1082 
1083  protected function outCorrectSolutionCmd()
1084  {
1085  $this->outCorrectSolution(); // cannot be named xxxCmd, because it's also called from context without Cmd in names
1086  }
1087 
1091  protected function outCorrectSolution(): void
1092  {
1093  if (!$this->object->getShowSolutionDetails()) {
1094  $this->tpl->setOnScreenMessage('info', $this->lng->txt("no_permission"), true);
1095  $this->ctrl->redirectByClass("ilobjtestgui", "infoScreen");
1096  }
1097 
1098  $testSession = $this->testSessionFactory->getSession();
1099  $active_id = $testSession->getActiveId();
1100 
1101  if (!($active_id > 0)) {
1102  $this->ctrl->redirectByClass("ilobjtestgui", "infoScreen");
1103  }
1104 
1105  $this->ctrl->saveParameter($this, "pass");
1106  $pass = (int) $this->testrequest->raw("pass");
1107 
1108  $active_id = (int) $this->testrequest->raw('evaluation');
1109 
1110  $test_sequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($active_id, $pass);
1111  $test_sequence->loadFromDb();
1112  $test_sequence->loadQuestions();
1113 
1114  if (!$test_sequence->questionExists($active_id)) {
1115  ilObjTestGUI::accessViolationRedirect();
1116  }
1117 
1118  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
1119  $test_sequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($active_id, $pass);
1120  $test_sequence->loadFromDb();
1121  $test_sequence->loadQuestions();
1122 
1123  $objectives_adapter = ilLOTestQuestionAdapter::getInstance($testSession);
1124  $objectives_list = $this->buildQuestionRelatedObjectivesList($objectives_adapter, $test_sequence);
1125  $objectives_list->loadObjectivesTitles();
1126  } else {
1127  $objectives_list = null;
1128  }
1129 
1130  $ilTabs = $this->tabs;
1131 
1132  if ($this instanceof ilTestEvalObjectiveOrientedGUI) {
1133  $ilTabs->setBackTarget(
1134  $this->lng->txt("tst_back_to_virtual_pass"),
1135  $this->ctrl->getLinkTarget($this, 'showVirtualPass')
1136  );
1137  } else {
1138  $ilTabs->setBackTarget(
1139  $this->lng->txt("tst_back_to_pass_details"),
1140  $this->ctrl->getLinkTarget($this, 'outUserPassDetails')
1141  );
1142  }
1143  $ilTabs->clearSubTabs();
1144 
1145  $this->tpl->setCurrentBlock("ContentStyle");
1146  $this->tpl->setVariable("LOCATION_CONTENT_STYLESHEET", ilObjStyleSheet::getContentStylePath(0));
1147  $this->tpl->parseCurrentBlock();
1148 
1149  $this->tpl->setCurrentBlock("SyntaxStyle");
1150  $this->tpl->setVariable("LOCATION_SYNTAX_STYLESHEET", ilObjStyleSheet::getSyntaxStylePath());
1151  $this->tpl->parseCurrentBlock();
1152 
1153  $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css", "Modules/Test"), "print");
1154  if ($this->object->getShowSolutionAnswersOnly()) {
1155  $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print_hide_content.css", "Modules/Test"), "print");
1156  }
1157 
1158  $solution = $this->getCorrectSolutionOutput($active_id, $active_id, $pass, $objectives_list);
1159 
1160  $this->tpl->setContent($solution);
1161  }
1162 
1163  protected function populatePassFinishDate(ilTemplate $tpl, ?int $pass_finish_date): void
1164  {
1165  if ($pass_finish_date === null) {
1166  return;
1167  }
1168  $old_value = ilDatePresentation::useRelativeDates();
1170  $pass_finish_date_string = ilDatePresentation::formatDate(new ilDateTime($pass_finish_date, IL_CAL_UNIX));
1172  $tpl->setVariable("PASS_FINISH_DATE_LABEL", $this->lng->txt('tst_pass_finished_on'));
1173  $tpl->setVariable("PASS_FINISH_DATE_VALUE", $pass_finish_date_string);
1174  }
1175 
1176  protected function populateExamId(ilTemplate $tpl, int $active_id, int $pass): void
1177  {
1178  if ($this->object->isShowExamIdInTestResultsEnabled()) {
1179  $tpl->setVariable('EXAM_ID_TXT', $this->lng->txt('exam_id'));
1180  $tpl->setVariable('EXAM_ID', ilObjTest::lookupExamId(
1181  $active_id,
1182  $pass
1183  ));
1184  }
1185  }
1186 
1187  public function getObject()
1188  {
1189  return $this->object;
1190  }
1191 }
static get(string $a_var)
populateExamId(ilTemplate $tpl, int $active_id, int $pass)
Readable part of repository interface to ilComponentDataDB.
ilComponentRepository $component_repository
getQuestionResultForTestUsers(int $question_id, int $test_id)
ilTestResultsPresentationFactory $results_presentation_factory
ilParticipantsTestResultsGUI: ilTestEvaluationGUI ilParticipantsTestResultsGUI: ilAssQuestionPageGUI...
getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, $overwrite_anonymity=false)
Returns the user data for a test results output.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ilTestResultsFactory $results_factory
const SCORE_LAST_PASS
Provides fluid interface to LoggingServices.
Class ChatMainBarProvider .
setObjectiveOrientedContainer(ilTestObjectiveOrientedContainer $objective_oriented_container)
getResultsOfUserOutput(ilTestSession $testSession, int $active_id, int $pass, ilParticipantsTestResultsGUI $target_gui, bool $show_pass_details=true, bool $show_answers=true, bool $show_question_only=false, bool $show_reached_points=false)
Output of the pass overview for a test called by a test participant.
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
Help GUI class.
ilGlobalTemplateInterface ilTemplate $tpl
sk 2023-08-01: We need this union type, even if it is wrong! To change this
static initDomEvent(?ilGlobalTemplateInterface $a_main_tpl=null)
Init YUI DomEvent used in Services/Calendar, Modules/Session, Modules/Test (Jan 2022) ...
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
getFilteredTestResult(int $active_id, int $pass, bool $considerHiddenQuestions, bool $considerOptionalQuestions)
setContextResultPresentation(bool $contextResultPresentation)
getResultsSignature()
Returns HTML code for a signature field.
static prepareFormOutput($a_str, bool $a_strip=false)
const IL_CAL_UNIX
static getStyleSheetLocation(string $mode="output", string $a_css_name="", string $a_css_location="")
get full style sheet file name (path inclusive) of current user
buildPassOverviewTableGUI(ilTestEvaluationGUI $target_gui)
static getRequestRequestStatisticDataRegisterByActiveId($activeId)
global $DIC
Definition: feed.php:28
getPassListOfAnswers(&$result_array, $active_id, $pass, $show_solutions=false, $only_answered_questions=false, $show_question_only=false, $show_reached_points=false, $anchorNav=false, ilTestQuestionRelatedObjectivesList $objectives_list=null, ilTestResultHeaderLabelBuilder $testResultHeaderLabelBuilder=null)
Returns the list of answers of a users test pass.
ilNavigationHistory $navigation_history
setParticipantData(ilTestParticipantData $participantData)
$objectives
static getInstance(ilTestSession $a_test_session)
static getSingleManualFeedback(int $active_id, int $question_id, int $pass)
getResultsHeadUserAndPass($active_id, $pass)
Returns the user and pass data for a test results output.
static http()
Fetches the global http state from ILIAS.
__construct(VocabulariesInterface $vocabularies)
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:546
getGradingMessageBuilder(int $active_id)
getCommand($cmd)
Retrieves the ilCtrl command.
static _getReachedPoints(int $active_id, int $question_id, int $pass)
buildQuestionRelatedObjectiveList(ilTestQuestionSequence $a_test_sequence, ilTestQuestionRelatedObjectivesList $a_objectives_list)
setBackTarget(string $a_title, string $a_target, string $a_frame="")
outCorrectSolution()
Creates an output of the solution of an answer compared to the correct solution.
string $key
Consumer key/client ID value.
Definition: System.php:193
Output class for assessment test evaluation.
buildPassDetailsOverviewTableGUI(ilTestServiceGUI|ilParticipantsTestResultsGUI $target_gui, string $target_cmd)
header include for all ilias files.
ilTestSessionFactory $testSessionFactory
Class ilTestPassOverviewTableGUI.
ArrayBasedRequestWrapper $post_wrapper
getCorrectSolutionOutput($question_id, $active_id, $pass, ilTestQuestionRelatedObjectivesList $objectives_list=null)
Returns an output of the solution to an answer compared to the correct solution.
ilObjectDataCache $obj_cache
static getContentStylePath(int $a_style_id, bool $add_random=true, bool $add_token=true)
get content style path static (to avoid full reading)
Last visited history for repository items.
ILIAS TestQuestionPool QuestionInfoService $questioninfo
Service class for tests.
setLastname(string $a_str)
getPassDetailsOverviewTableGUI(array $result_array, int $active_id, int $pass, ilTestServiceGUI|ilParticipantsTestResultsGUI $target_gui, string $target_cmd, ilTestQuestionRelatedObjectivesList $objectives_list=null, bool $multiple_objectives_involved=true)
Error Handling & global info handling.
ilTestParticipantData $participantData
ilTestObjectiveOrientedContainer $objective_oriented_container
buildQuestionRelatedObjectivesList(ilLOTestQuestionAdapter $objectives_adapter, ilTestQuestionSequence $test_sequence)
static _getManualScoring()
Retrieve the manual scoring settings.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
executeCommand()
execute command
Service GUI class for tests.
static setUseRelativeDates(bool $a_status)
set use relative dates
populatePassFinishDate(ilTemplate $tpl, ?int $pass_finish_date)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
InternalRequestService $testrequest
GlobalScreenServices $global_screen
getPassListOfAnswersWithScoring(&$result_array, $active_id, $pass, $show_solutions=false)
Returns the list of answers of a users test pass and offers a scoring option.
ilTestParticipantAccessFilterFactory $participant_access_filter
getPassOverviewTableData(ilTestSession $testSession, $passes, $withResults)
This method uses the data of a given test pass to create an evaluation for displaying into a table us...
LoggingServices $logging_services
ilTestSequenceFactory $testSequenceFactory
static lookupExamId($active_id, $pass)
static _lookupLogin(int $a_user_id)