ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilTestServiceGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
23 use ILIAS\Test\Results\Data\Factory as ResultsDataFactory;
25 use ILIAS\Test\Results\Presentation\TitlesBuilder as ResultsTitlesBuilder;
26 use ILIAS\Test\Questions\Properties\Repository as TestQuestionsRepository;
36 use ILIAS\Style\Content\Service as ContentStyle;
37 
53 {
54  protected readonly RequestDataCollector $testrequest;
56  protected readonly TestQuestionsRepository $testquestionsrepository;
57  protected ?ilTestService $service = null;
58  protected readonly ilDBInterface $db;
59  protected readonly ilLanguage $lng;
60  protected readonly TestLogger $logger;
61  protected readonly ilHelpGUI $help;
62  protected readonly ilRbacSystem $rbac_system;
63 
70  protected readonly ContentStyle $content_style;
71  protected readonly ilErrorHandling $error;
72  protected ilAccess $access;
73  protected readonly HTTPServices $http;
74  protected readonly ilCtrlInterface $ctrl;
75  protected readonly ilToolbarGUI $toolbar;
76  protected readonly ilTabsGUI $tabs;
77  protected readonly ilObjectDataCache $obj_cache;
79  protected readonly ilObjUser $user;
82  protected readonly Refinery $refinery;
83  protected readonly UIFactory $ui_factory;
84  protected readonly UIRenderer $ui_renderer;
85  protected readonly SkillService $skills_service;
86  protected readonly ilTestShuffler $shuffler;
87  protected readonly ResultsDataFactory $results_data_factory;
89 
90  protected readonly ILIAS $ilias;
91  protected readonly ilSetting $settings;
93  protected readonly ilTree $tree;
94  protected int $ref_id;
95 
100 
102 
104 
105  private bool $contextResultPresentation = true;
106 
107  public function isContextResultPresentation(): bool
108  {
110  }
111 
112  public function setContextResultPresentation(bool $contextResultPresentation)
113  {
114  $this->contextResultPresentation = $contextResultPresentation;
115  }
116 
123  public function __construct(
124  protected ilObjTest $object
125  ) {
127  global $DIC;
128  $this->lng = $DIC['lng'];
129  $this->tpl = $DIC['tpl'];
130  $this->content_style = $DIC->contentStyle();
131  $this->error = $DIC['ilErr'];
132  $this->access = $DIC['ilAccess'];
133  $this->http = $DIC['http'];
134  $this->ctrl = $DIC['ilCtrl'];
135  $this->user = $DIC->user();
136  $this->ilias = $DIC['ilias'];
137  $this->settings = $DIC['ilSetting'];
138  $this->global_screen = $DIC['global_screen'];
139  $this->tree = $DIC['tree'];
140  $this->db = $DIC['ilDB'];
141  $this->component_repository = $DIC['component.repository'];
142  $this->navigation_history = $DIC['ilNavigationHistory'];
143  $this->tabs = $DIC['ilTabs'];
144  $this->toolbar = $DIC['ilToolbar'];
145  $this->help = $DIC['ilHelp'];
146  $this->refinery = $DIC->refinery();
147  $this->ui_factory = $DIC['ui.factory'];
148  $this->ui_renderer = $DIC['ui.renderer'];
149  $this->rbac_system = $DIC['rbacsystem'];
150  $this->obj_cache = $DIC['ilObjDataCache'];
151  $this->skills_service = $DIC->skills();
152  $this->post_wrapper = $DIC->http()->wrapper()->post();
153 
154  $local_dic = $object->getLocalDIC();
155  $this->testrequest = $local_dic['request_data_collector'];
156  $this->logger = $local_dic['logging.logger'];
157  $this->participant_access_filter = $local_dic['participant.access_filter.factory'];
158  $this->shuffler = $local_dic['shuffler'];
159  $this->results_data_factory = $local_dic['results.data.factory'];
160  $this->results_presentation_factory = $local_dic['results.presentation.factory'];
161  $this->questionrepository = $local_dic['question.general_properties.repository'];
162  $this->testquestionsrepository = $local_dic['questions.properties.repository'];
163  $this->test_result_repository = $local_dic['results.data.repository'];
164 
165  $this->service = new ilTestService($this->object, $this->db, $this->questionrepository);
166 
167  $this->lng->loadLanguageModule('cert');
168  $this->ref_id = $this->object->getRefId();
169  $this->test_session_factory = new ilTestSessionFactory($this->object, $this->db, $this->user);
170  $this->test_sequence_factory = new ilTestSequenceFactory($this->object, $this->db, $this->questionrepository);
171  $this->objective_oriented_container = null;
172  }
173 
174  public function setParticipantData(ilTestParticipantData $participantData): void
175  {
176  $this->participantData = $participantData;
177  }
178 
180  {
181  return $this->participantData;
182  }
183 
188  public function getPassOverviewTableData(
189  ilTestSession $test_session,
190  array $passes,
191  bool $with_results
192  ): array {
193  $data = [];
194 
195  $objective_oriented_presentation = $this->getObjectiveOrientedContainer()
196  ?->isObjectiveOrientedPresentationRequired() ?? false;
197 
198  if ($objective_oriented_presentation) {
199  $consider_hidden_questions = false;
200 
201  $objectives_adapter = ilLOTestQuestionAdapter::getInstance($test_session);
202  } else {
203  $consider_hidden_questions = true;
204  }
205 
206  $scored_pass = \ilObjTest::_getResultPass($test_session->getActiveId());
207 
208  foreach ($passes as $pass) {
209  $row = [
210  'scored' => false,
211  'pass' => $pass,
212  'date' => ilObjTest::lookupLastTestPassAccess($test_session->getActiveId(), $pass)
213  ];
214  $considerOptionalQuestions = true;
215 
216  if ($objective_oriented_presentation) {
217  $test_sequence = $this->test_sequence_factory->getSequenceByActiveIdAndPass($test_session->getActiveId(), $pass);
218  $test_sequence->loadFromDb();
219  $test_sequence->loadQuestions();
220 
221  if ($this->object->isRandomTest() && !$test_sequence->isAnsweringOptionalQuestionsConfirmed()) {
222  $considerOptionalQuestions = false;
223  }
224 
225  $test_sequence->setConsiderHiddenQuestionsEnabled($consider_hidden_questions);
226  $test_sequence->setConsiderOptionalQuestionsEnabled($considerOptionalQuestions);
227 
228  $objectives_list = $this->buildQuestionRelatedObjectivesList($objectives_adapter, $test_sequence);
229  $objectives_list->loadObjectivesTitles();
230 
231  $row['objectives'] = $objectives_list->getUniqueObjectivesStringForQuestions($test_sequence->getUserSequenceQuestions());
232  }
233 
234  if (!$with_results) {
235  $data[] = $row;
236  continue;
237  }
238 
239  $result_array = $this->object->getTestResult(
240  $test_session->getActiveId(),
241  $pass,
242  false,
243  $consider_hidden_questions,
244  $considerOptionalQuestions
245  );
246 
247  if (!$result_array['pass']['total_max_points']) {
248  $row['percentage'] = 0;
249  } else {
250  $row['percentage'] = ($result_array['pass']['total_reached_points'] / $result_array['pass']['total_max_points']) * 100;
251  }
252 
253  $row['max_points'] = $result_array['pass']['total_max_points'];
254  $row['reached_points'] = $result_array['pass']['total_reached_points'];
255  $row['scored'] = ($pass == $scored_pass);
256  $row['num_workedthrough_questions'] = $result_array['pass']['num_workedthrough'];
257  $row['num_questions_total'] = $result_array['pass']['num_questions_total'];
258  $data[] = $row;
259  }
260 
261  return $data;
262  }
263 
267  public function setObjectiveOrientedContainer(ilTestObjectiveOrientedContainer $objective_oriented_container)
268  {
269  $this->objective_oriented_container = $objective_oriented_container;
270  }
271 
276  {
278  }
279 
283  public function executeCommand()
284  {
285  $cmd = $this->ctrl->getCmd();
286  $next_class = $this->ctrl->getNextClass($this);
287 
288  switch ($next_class) {
289  default:
290  $ret = &$this->$cmd();
291  break;
292  }
293  return $ret;
294  }
295 
297  {
298  $table = new ilTestPassOverviewTableGUI($target_gui, '');
299 
300  $table->setPdfPresentationEnabled(
301  $this->testrequest->isset('pdf') && $this->testrequest->raw('pdf') == 1
302  );
303 
304  $table->setObjectiveOrientedPresentationEnabled(
305  $this->getObjectiveOrientedContainer()?->isObjectiveOrientedPresentationRequired() ?? false
306  );
307 
308  return $table;
309  }
310 
321  public function getPassListOfAnswers(
322  &$result_array,
323  $active_id,
324  $pass,
325  $show_solutions = false,
326  $only_answered_questions = false,
327  $show_question_only = false,
328  $show_reached_points = false,
329  $anchorNav = false,
330  ?ilTestQuestionRelatedObjectivesList $objectives_list = null,
331  ?ResultsTitlesBuilder $testResultHeaderLabelBuilder = null
332  ): string {
333  $maintemplate = new ilTemplate('tpl.il_as_tst_list_of_answers.html', true, true, 'components/ILIAS/Test');
334 
335  $counter = 1;
336  // output of questions with solutions
337  foreach ($result_array as $question_data) {
338  if (!array_key_exists('workedthrough', $question_data)) {
339  $question_data['workedthrough'] = 0;
340  }
341  if (!array_key_exists('qid', $question_data)) {
342  $question_data['qid'] = -1;
343  }
344 
345  if (($question_data['workedthrough'] == 1) || ($only_answered_questions == false)) {
346  $template = new ilTemplate('tpl.il_as_qpl_question_printview.html', true, true, 'components/ILIAS/TestQuestionPool');
347  $question_id = $question_data["qid"] ?? null;
348  if ($question_id !== null
349  && $question_id !== -1
350  && is_numeric($question_id)) {
351  $maintemplate->setCurrentBlock('printview_question');
352  $question_gui = $this->object->createQuestionGUI("", $question_id);
353 
354  $question_gui->getObject()->setShuffler($this->shuffler->getAnswerShuffleFor(
355  (int) $question_id,
356  (int) $active_id,
357  (int) $pass
358  ));
359  if (is_object($question_gui)) {
360  if ($anchorNav) {
361  $template->setCurrentBlock('block_id');
362  $template->setVariable('BLOCK_ID', "detailed_answer_block_act_{$active_id}_qst_{$question_id}");
363  $template->parseCurrentBlock();
364 
365  $template->setCurrentBlock('back_anchor');
366  $template->setVariable('HREF_BACK_ANCHOR', "#pass_details_tbl_row_act_{$active_id}_qst_{$question_id}");
367  $template->setVariable('TXT_BACK_ANCHOR', $this->lng->txt('tst_back_to_question_list'));
368  $template->parseCurrentBlock();
369  }
370 
371  if ($show_reached_points) {
372  $template->setCurrentBlock("result_points");
373  $template->setVariable("RESULT_POINTS", $this->lng->txt("tst_reached_points") . ": " . $question_gui->getObject()->getReachedPoints($active_id, $pass) . " " . $this->lng->txt("of") . " " . $question_gui->getObject()->getMaximumPoints());
374  $template->parseCurrentBlock();
375  }
376  $template->setVariable("COUNTER_QUESTION", $counter . ". ");
377  $template->setVariable("TXT_QUESTION_ID", $this->lng->txt('question_id_short'));
378  $template->setVariable("QUESTION_ID", $question_gui->getObject()->getId());
379  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->getObject()->getTitleForHTMLOutput()));
380 
381  if ($objectives_list !== null) {
382  $objectives = $this->lng->txt('tst_res_lo_objectives_header') . ': ';
383  $objectives .= $objectives_list->getQuestionRelatedObjectiveTitles($question_gui->getObject()->getId());
384  $template->setVariable("OBJECTIVES", $objectives);
385  }
386 
387  $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? true : false;
388 
389  $show_feedback = $this->isContextResultPresentation() && $this->object->getShowSolutionFeedback();
390  $show_best_solution = $this->isContextResultPresentation() && $show_solutions;
391  $show_graphical_output = $this->isContextResultPresentation();
392 
393  if ($show_best_solution) {
394  $compare_template = new ilTemplate('tpl.il_as_tst_answers_compare.html', true, true, 'components/ILIAS/Test');
395  $test_session = $this->test_session_factory->getSession($active_id);
396  if ($pass <= $test_session->getLastFinishedPass()) {
397  $compare_template->setVariable("HEADER_PARTICIPANT", $this->lng->txt('tst_header_participant'));
398  } else {
399  $compare_template->setVariable("HEADER_PARTICIPANT", $this->lng->txt('tst_header_participant_no_answer'));
400  }
401 
402  $compare_template->setVariable("HEADER_SOLUTION", $this->lng->txt('tst_header_solution'));
403  $result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_graphical_output, false, $show_question_only, $show_feedback);
404  $best_output = $question_gui->getSolutionOutput($active_id, $pass, false, false, $show_question_only, false, true);
405 
406  $compare_template->setVariable('PARTICIPANT', $result_output);
407  $compare_template->setVariable('SOLUTION', $best_output);
408  $template->setVariable('SOLUTION_OUTPUT', $compare_template->get());
409  } else {
410  $result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_graphical_output, false, $show_question_only, $show_feedback);
411  $template->setVariable('SOLUTION_OUTPUT', $result_output);
412  }
413 
414  $maintemplate->setCurrentBlock('printview_question');
415  $maintemplate->setVariable("QUESTION_PRINTVIEW", $template->get());
416  $maintemplate->parseCurrentBlock();
417  $counter++;
418  }
419  }
420  }
421  }
422 
423  if ($testResultHeaderLabelBuilder !== null) {
424  if ($pass !== null) {
425  $headerText = $testResultHeaderLabelBuilder->getListOfAnswersHeaderLabel($pass + 1);
426  } else {
427  $headerText = $testResultHeaderLabelBuilder->getVirtualListOfAnswersHeaderLabel();
428  }
429  } else {
430  $headerText = '';
431  }
432 
433  $maintemplate->setVariable('RESULTS_OVERVIEW', $headerText);
434  return $maintemplate->get();
435  }
436 
437  protected function getPassDetailsOverviewTableGUI(
438  array $result_array,
439  int $active_id,
440  int $pass,
441  ilTestServiceGUI $target_gui,
442  string $target_cmd,
443  ?ilTestQuestionRelatedObjectivesList $objectives_list = null,
444  bool $multiple_objectives_involved = true
446  $this->ctrl->setParameter($target_gui, 'active_id', $active_id);
447  $this->ctrl->setParameter($target_gui, 'pass', $pass);
448 
449  $table_gui = $this->buildPassDetailsOverviewTableGUI($target_gui, $target_cmd);
450 
451  if ($objectives_list !== null) {
452  $table_gui->setQuestionRelatedObjectivesList($objectives_list);
453  $table_gui->setObjectiveOrientedPresentationEnabled(true);
454  }
455 
456  $table_gui->setMultipleObjectivesInvolved($multiple_objectives_involved);
457 
458  $table_gui->setActiveId($active_id);
459  $table_gui->setShowSuggestedSolution(false);
460 
461  $users_question_solutions = [];
462 
463  foreach ($result_array as $key => $val) {
464  if ($key === 'test' || $key === 'pass') {
465  continue;
466  }
467 
468  if ($this->object->getShowSolutionSuggested() && strlen($val['solution'])) {
469  $table_gui->setShowSuggestedSolution(true);
470  }
471 
472  if (isset($val['pass'])) {
473  $table_gui->setPassColumnEnabled(true);
474  }
475 
476  $users_question_solutions[$key] = $val;
477  }
478 
479  $table_gui->initColumns();
480 
481  $table_gui->setFilterCommand($target_cmd . 'SetTableFilter');
482  $table_gui->setResetCommand($target_cmd . 'ResetTableFilter');
483 
484  $table_gui->setData($users_question_solutions);
485 
486  return $table_gui;
487  }
488 
495  public function getResultsSignature(): string
496  {
497  if ($this->object->getShowSolutionSignature() && !$this->object->getAnonymity()) {
498  $template = new ilTemplate("tpl.il_as_tst_results_userdata_signature.html", true, true, "components/ILIAS/Test");
499  $template->setVariable("TXT_DATE", $this->lng->txt("date"));
502  $template->setVariable("VALUE_DATE", ilDatePresentation::formatDate(new ilDate(time(), IL_CAL_UNIX)));
504  $template->setVariable("TXT_SIGNATURE", $this->lng->txt("tst_signature"));
505  $template->setVariable("IMG_SPACER", ilUtil::getImagePath("media/spacer.png"));
506  return $template->get();
507  } else {
508  return "";
509  }
510  }
511 
521  public function getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, $overwrite_anonymity = false): string
522  {
523  if (!is_object($testSession)) {
524  throw new InvalidArgumentException('Not an object, expected ilTestSession');
525  }
526  $template = new ilTemplate("tpl.il_as_tst_results_userdata.html", true, true, "components/ILIAS/Test");
527  $user_id = $this->object->_getUserIdFromActiveId($active_id);
528  if (strlen(ilObjUser::_lookupLogin($user_id)) > 0) {
529  $user = new ilObjUser($user_id);
530  } else {
531  $user = new ilObjUser();
532  $user->setLastname($this->lng->txt('deleted_user'));
533  }
534  $t = $testSession->getSubmittedTimestamp();
535  if (!$t) {
536  $t = $this->object->_getLastAccess($testSession->getActiveId());
537  }
538 
539  if ($this->getObjectiveOrientedContainer()?->isObjectiveOrientedPresentationRequired()) {
540  $uname = $this->object->userLookupFullName($user_id, $overwrite_anonymity);
541  $template->setCurrentBlock('name');
542  $template->setVariable('TXT_USR_NAME', $this->lng->txt("name"));
543  $template->setVariable('VALUE_USR_NAME', $uname);
544  $template->parseCurrentBlock();
545  }
546 
547  $title_matric = "";
548  if (strlen($user->getMatriculation()) && (($this->object->getAnonymity() == false) || ($overwrite_anonymity))) {
549  $template->setCurrentBlock("matriculation");
550  $template->setVariable("TXT_USR_MATRIC", $this->lng->txt("matriculation"));
551  $template->setVariable("VALUE_USR_MATRIC", $user->getMatriculation());
552  $template->parseCurrentBlock();
553  $title_matric = " - " . $this->lng->txt("matriculation") . ": " . $user->getMatriculation();
554  }
555 
556  $invited_user = array_pop($this->object->getInvitedUsers($user_id));
557  $title_client = '';
558  $template->setVariable("TXT_TEST_TITLE", $this->lng->txt("title"));
559  $template->setVariable("VALUE_TEST_TITLE", $this->object->getTitle());
560 
561  // change the pagetitle (tab title or title in title bar of window)
562  $pagetitle = $this->object->getTitle() . $title_matric . $title_client;
563  $this->tpl->setHeaderPageTitle($pagetitle);
564 
565  return $template->get();
566  }
567 
577  public function getCorrectSolutionOutput($question_id, $active_id, $pass, ?ilTestQuestionRelatedObjectivesList $objectives_list = null): string
578  {
579  $ilUser = $this->user;
580 
581  $test_id = $this->object->getTestId();
582  $question_gui = $this->object->createQuestionGUI("", $question_id);
583 
584  $template = new ilTemplate("tpl.il_as_tst_correct_solution_output.html", true, true, "components/ILIAS/Test");
585  $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? true : false;
586  $result_output = $question_gui->getSolutionOutput($active_id, $pass, true, false, $show_question_only, $this->object->getShowSolutionFeedback(), false, false, true);
587  $best_output = $question_gui->getSolutionOutput($active_id, $pass, false, false, $show_question_only, false, true, false, false);
588  if ($this->object->getShowSolutionFeedback() && $this->testrequest->raw('cmd') != 'outCorrectSolution') {
589  $specificAnswerFeedback = $question_gui->getSpecificFeedbackOutput(
590  $question_gui->getObject()->fetchIndexedValuesFromValuePairs(
591  $question_gui->getObject()->getSolutionValues($active_id, $pass)
592  )
593  );
594  if (strlen($specificAnswerFeedback)) {
595  $template->setCurrentBlock("outline_specific_feedback");
596  $template->setVariable("OUTLINE_SPECIFIC_FEEDBACK", $specificAnswerFeedback);
597  $template->parseCurrentBlock();
598  }
599  }
600  $template->setVariable("TEXT_YOUR_SOLUTION", $this->lng->txt("tst_your_answer_was"));
601  $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
602  // I set both old and new since the old one is set as well in several places.
603  $maxpoints = $question_gui->getObject()->getMaximumPoints();
604  if ($maxpoints == 1) {
605  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->getObject()->getTitleForHTMLOutput()) . " (" . $maxpoints . " " . $this->lng->txt("point") . ")");
606  } else {
607  $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->getObject()->getTitleForHTMLOutput()) . " (" . $maxpoints . " " . $this->lng->txt("points") . ")");
608  }
609  if ($objectives_list !== null) {
610  $objectives = $this->lng->txt('tst_res_lo_objectives_header') . ': ';
611  $objectives .= $objectives_list->getQuestionRelatedObjectiveTitles($question_gui->getObject()->getId());
612  $template->setVariable('OBJECTIVES', $objectives);
613  }
614  $template->setVariable("SOLUTION_OUTPUT", $result_output);
615  $template->setVariable("RECEIVED_POINTS", sprintf($this->lng->txt("you_received_a_of_b_points"), $question_gui->getObject()->getReachedPoints($active_id, $pass), $maxpoints));
616  $template->setVariable("FORMACTION", $this->ctrl->getFormAction($this));
617  $template->setVariable("BACKLINK_TEXT", "&lt;&lt; " . $this->lng->txt("back"));
618  return $template->get();
619  }
620 
622  ilTestServiceGUI $target_gui,
623  string $target_cmd
625  return new ilTestPassDetailsOverviewTableGUI($this->ctrl, $target_gui, $target_cmd);
626  }
627 
628  protected function isGradingMessageRequired(): bool
629  {
630  $session = $this->test_session_factory->getSession();
631  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()
632  || $this->object->getScoreSettings()->getScoringSettings()->getPassScoring() === ilObjTest::SCORE_LAST_PASS
633  && $session->getLastFinishedPass() < $session->getLastStartedPass()) {
634  return false;
635  }
636 
637  if ($this->object->isShowGradingStatusEnabled()
638  || $this->object->isShowGradingMarkEnabled()) {
639  return true;
640  }
641 
642  return false;
643  }
644 
645  protected function getGradingMessageBuilder(int $active_id): ilTestGradingMessageBuilder
646  {
647  return new ilTestGradingMessageBuilder(
648  $this->lng,
649  $this->tpl,
650  $this->object,
651  $this->test_result_repository->getTestResult($active_id)
652  );
653  }
654 
656  ilLOTestQuestionAdapter $objectives_adapter,
657  ilTestQuestionSequence $test_sequence
659  $questionRelatedObjectivesList = new ilTestQuestionRelatedObjectivesList();
660 
661  $objectives_adapter->buildQuestionRelatedObjectiveList($test_sequence, $questionRelatedObjectivesList);
662 
663  return $questionRelatedObjectivesList;
664  }
665 
666  protected function populateContent(string $content): void
667  {
668  $this->tpl->setContent($content);
669  }
670 
671  protected function outCorrectSolutionCmd(): void
672  {
673  $this->outCorrectSolution(); // cannot be named xxxCmd, because it's also called from context without Cmd in names
674  }
675 
676  protected function outCorrectSolution(): void
677  {
678  if (!$this->object->getShowSolutionDetails()) {
679  $this->tpl->setOnScreenMessage('info', $this->lng->txt("no_permission"), true);
680  $this->ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, ilInfoScreenGUI::class]);
681  }
682 
683  $testSession = $this->test_session_factory->getSession();
684  $active_id = $testSession->getActiveId();
685 
686  if (!($active_id > 0)) {
687  $this->ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, ilInfoScreenGUI::class]);
688  }
689 
690  $this->ctrl->saveParameter($this, "pass");
691  $pass = (int) $this->testrequest->raw("pass");
692 
693  $active_id = (int) $this->testrequest->raw('evaluation');
694 
695  $test_sequence = $this->test_sequence_factory->getSequenceByActiveIdAndPass($active_id, $pass);
696  $test_sequence->loadFromDb();
697  $test_sequence->loadQuestions();
698 
699  if (!$test_sequence->questionExists($active_id)) {
700  ilObjTestGUI::accessViolationRedirect();
701  }
702 
703  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
704  $test_sequence = $this->test_sequence_factory->getSequenceByActiveIdAndPass($active_id, $pass);
705  $test_sequence->loadFromDb();
706  $test_sequence->loadQuestions();
707 
708  $objectives_adapter = ilLOTestQuestionAdapter::getInstance($testSession);
709  $objectives_list = $this->buildQuestionRelatedObjectivesList($objectives_adapter, $test_sequence);
710  $objectives_list->loadObjectivesTitles();
711  } else {
712  $objectives_list = null;
713  }
714 
715  $ilTabs = $this->tabs;
716 
717  if ($this instanceof ilTestEvalObjectiveOrientedGUI) {
718  $ilTabs->setBackTarget(
719  $this->lng->txt("tst_back_to_virtual_pass"),
720  $this->ctrl->getLinkTarget($this, 'showVirtualPass')
721  );
722  } else {
723  $ilTabs->setBackTarget(
724  $this->lng->txt("tst_back_to_pass_details"),
725  $this->ctrl->getLinkTarget($this, 'outUserPassDetails')
726  );
727  }
728  $ilTabs->clearSubTabs();
729 
730  $this->tpl->setCurrentBlock("ContentStyle");
731  $this->tpl->setVariable("LOCATION_CONTENT_STYLESHEET", ilObjStyleSheet::getContentStylePath(0));
732  $this->tpl->parseCurrentBlock();
733 
734  $this->tpl->setCurrentBlock("SyntaxStyle");
735  $this->tpl->setVariable("LOCATION_SYNTAX_STYLESHEET", ilObjStyleSheet::getSyntaxStylePath());
736  $this->tpl->parseCurrentBlock();
737 
738  $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css"), "print");
739  if ($this->object->getShowSolutionAnswersOnly()) {
740  $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print_hide_content.css"), "print");
741  }
742 
743  $solution = $this->getCorrectSolutionOutput($active_id, $active_id, $pass, $objectives_list);
744 
745  $this->tpl->setContent($solution);
746  }
747 
748  protected function populatePassFinishDate(ilTemplate $tpl, ?int $pass_finish_date): void
749  {
750  if ($pass_finish_date === null) {
751  return;
752  }
755  $pass_finish_date_string = ilDatePresentation::formatDate(new ilDateTime($pass_finish_date, IL_CAL_UNIX));
757  $tpl->setVariable("PASS_FINISH_DATE_LABEL", $this->lng->txt('tst_pass_finished_on'));
758  $tpl->setVariable("PASS_FINISH_DATE_VALUE", $pass_finish_date_string);
759  }
760 
761  protected function populateExamId(ilTemplate $tpl, int $active_id, int $pass): void
762  {
763  if ($this->object->isShowExamIdInTestResultsEnabled()) {
764  $tpl->setVariable('EXAM_ID_TXT', $this->lng->txt('exam_id'));
765  $tpl->setVariable('EXAM_ID', ilObjTest::lookupExamId(
766  $active_id,
767  $pass
768  ));
769  }
770  }
771 
772  public function getObject(): ilObjTest
773  {
774  return $this->object;
775  }
776 }
readonly HTTPServices $http
static array static setUseRelativeDates(bool $a_status)
set use relative dates
static getStyleSheetLocation(string $mode="output", string $a_css_name="")
get full style sheet file name (path inclusive) of current user
populateExamId(ilTemplate $tpl, int $active_id, int $pass)
Readable part of repository interface to ilComponentDataDB.
readonly Refinery $refinery
getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, $overwrite_anonymity=false)
Returns the user data for a test results output.
readonly ilTestShuffler $shuffler
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
readonly ilCtrlInterface $ctrl
getCorrectSolutionOutput($question_id, $active_id, $pass, ?ilTestQuestionRelatedObjectivesList $objectives_list=null)
Returns an output of the solution to an answer compared to the correct solution.
Interface Observer Contains several chained tasks and infos about them.
readonly TestQuestionsRepository $testquestionsrepository
readonly GlobalScreenServices $global_screen
setObjectiveOrientedContainer(ilTestObjectiveOrientedContainer $objective_oriented_container)
Help GUI class.
ilGlobalTemplateInterface ilTemplate $tpl
sk 2023-08-01: We need this union type, even if it is wrong! To change this
readonly ilLanguage $lng
setContextResultPresentation(bool $contextResultPresentation)
readonly GeneralQuestionPropertiesRepository $questionrepository
getResultsSignature()
Returns HTML code for a signature field.
readonly ArrayBasedRequestWrapper $post_wrapper
const IL_CAL_UNIX
readonly RequestDataCollector $testrequest
getPassDetailsOverviewTableGUI(array $result_array, int $active_id, int $pass, ilTestServiceGUI $target_gui, string $target_cmd, ?ilTestQuestionRelatedObjectivesList $objectives_list=null, bool $multiple_objectives_involved=true)
buildPassOverviewTableGUI(ilTestEvaluationGUI $target_gui)
readonly TestLogger $logger
readonly ResultsDataFactory $results_data_factory
readonly ilComponentRepository $component_repository
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
TestResultRepository $test_result_repository
setParticipantData(ilTestParticipantData $participantData)
$objectives
ilTestSequenceFactory $test_sequence_factory
static getInstance(ilTestSession $a_test_session)
static http()
Fetches the global http state from ILIAS.
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:544
readonly UIRenderer $ui_renderer
getGradingMessageBuilder(int $active_id)
readonly ilHelpGUI $help
readonly ilDBInterface $db
static _getResultPass($active_id)
Retrieves the pass number that should be counted for a given user.
buildQuestionRelatedObjectiveList(ilTestQuestionSequence $a_test_sequence, ilTestQuestionRelatedObjectivesList $a_objectives_list)
readonly ilNavigationHistory $navigation_history
getPassOverviewTableData(ilTestSession $test_session, array $passes, bool $with_results)
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, ?ResultsTitlesBuilder $testResultHeaderLabelBuilder=null)
Returns the list of answers of a users test pass.
global $DIC
Definition: shib_login.php:26
readonly ResultsPresentationFactory $results_presentation_factory
setBackTarget(string $a_title, string $a_target, string $a_frame="")
Output class for assessment test evaluation.
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
Class ilObjForumAdministration.
Class ilTestPassOverviewTableGUI.
readonly ilObjUser $user
const SCORE_LAST_PASS
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.
readonly ilRbacSystem $rbac_system
readonly ilObjectDataCache $obj_cache
Service class for tests.
readonly UIFactory $ui_factory
ilTestParticipantData $participantData
ilTestObjectiveOrientedContainer $objective_oriented_container
buildQuestionRelatedObjectivesList(ilLOTestQuestionAdapter $objectives_adapter, ilTestQuestionSequence $test_sequence)
__construct(Container $dic, ilPlugin $plugin)
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ?ilObjUser $user=null,)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
readonly ilTabsGUI $tabs
executeCommand()
execute command
buildPassDetailsOverviewTableGUI(ilTestServiceGUI $target_gui, string $target_cmd)
readonly ilSetting $settings
Service GUI class for tests.
ilTestSessionFactory $test_session_factory
populatePassFinishDate(ilTemplate $tpl, ?int $pass_finish_date)
populateContent(string $content)
readonly SkillService $skills_service
ilTestParticipantAccessFilterFactory $participant_access_filter
readonly ilErrorHandling $error
readonly ContentStyle $content_style
readonly ilToolbarGUI $toolbar
static lookupExamId($active_id, $pass)
static _lookupLogin(int $a_user_id)