ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilTestServiceGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
23use ILIAS\Test\Results\Data\Factory as ResultsDataFactory;
24use ILIAS\Test\Results\Presentation\Factory as ResultsPresentationFactory;
25use ILIAS\Test\Results\Presentation\TitlesBuilder as ResultsTitlesBuilder;
26use ILIAS\Test\Questions\Properties\Repository as TestQuestionsRepository;
27use ILIAS\Test\Results\Data\Repository as TestResultRepository;
29use ILIAS\UI\Factory as UIFactory;
30use ILIAS\UI\Renderer as UIRenderer;
31use ILIAS\HTTP\Services as HTTPServices;
32use ILIAS\GlobalScreen\Services as GlobalScreenServices;
33use ILIAS\Refinery\Factory as Refinery;
36use ILIAS\Style\Content\Service as ContentStyle;
37
53{
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;
88 protected readonly ResultsPresentationFactory $results_presentation_factory;
89
90 protected readonly ILIAS $ilias;
91 protected readonly ilSetting $settings;
92 protected readonly GlobalScreenServices $global_screen;
93 protected readonly ilTree $tree;
94 protected int $ref_id;
95
99 protected TestResultRepository $test_result_repository;
100
102
104
105 private bool $contextResultPresentation = true;
106
107 public function isContextResultPresentation(): bool
108 {
110 }
111
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
175 {
176 $this->participantData = $participantData;
177 }
178
180 {
182 }
183
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 {
277 return $this->objective_oriented_container;
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(
411 $active_id,
412 $pass,
413 $show_graphical_output,
414 false,
415 $show_question_only,
416 $show_feedback,
417 false,
418 false,
419 true,
420 $show_feedback
421 );
422 $template->setVariable('SOLUTION_OUTPUT', $result_output);
423 }
424
425 $maintemplate->setCurrentBlock('printview_question');
426 $maintemplate->setVariable("QUESTION_PRINTVIEW", $template->get());
427 $maintemplate->parseCurrentBlock();
428 $counter++;
429 }
430 }
431 }
432 }
433
434 if ($testResultHeaderLabelBuilder !== null) {
435 if ($pass !== null) {
436 $headerText = $testResultHeaderLabelBuilder->getListOfAnswersHeaderLabel($pass + 1);
437 } else {
438 $headerText = $testResultHeaderLabelBuilder->getVirtualListOfAnswersHeaderLabel();
439 }
440 } else {
441 $headerText = '';
442 }
443
444 $maintemplate->setVariable('RESULTS_OVERVIEW', $headerText);
445 return $maintemplate->get();
446 }
447
449 array $result_array,
450 int $active_id,
451 int $pass,
452 ilTestServiceGUI $target_gui,
453 string $target_cmd,
454 ?ilTestQuestionRelatedObjectivesList $objectives_list = null,
455 bool $multiple_objectives_involved = true
457 $this->ctrl->setParameter($target_gui, 'active_id', $active_id);
458 $this->ctrl->setParameter($target_gui, 'pass', $pass);
459
460 $table_gui = $this->buildPassDetailsOverviewTableGUI($target_gui, $target_cmd);
461
462 if ($objectives_list !== null) {
463 $table_gui->setQuestionRelatedObjectivesList($objectives_list);
464 $table_gui->setObjectiveOrientedPresentationEnabled(true);
465 }
466
467 $table_gui->setMultipleObjectivesInvolved($multiple_objectives_involved);
468
469 $table_gui->setActiveId($active_id);
470 $table_gui->setShowSuggestedSolution(false);
471
472 $users_question_solutions = [];
473
474 foreach ($result_array as $key => $val) {
475 if ($key === 'test' || $key === 'pass') {
476 continue;
477 }
478
479 if ($this->object->getShowSolutionSuggested() && strlen($val['solution'])) {
480 $table_gui->setShowSuggestedSolution(true);
481 }
482
483 if (isset($val['pass'])) {
484 $table_gui->setPassColumnEnabled(true);
485 }
486
487 $users_question_solutions[$key] = $val;
488 }
489
490 $table_gui->initColumns();
491
492 $table_gui->setFilterCommand($target_cmd . 'SetTableFilter');
493 $table_gui->setResetCommand($target_cmd . 'ResetTableFilter');
494
495 $table_gui->setData($users_question_solutions);
496
497 return $table_gui;
498 }
499
506 public function getResultsSignature(): string
507 {
508 if ($this->object->getShowSolutionSignature() && !$this->object->getAnonymity()) {
509 $template = new ilTemplate("tpl.il_as_tst_results_userdata_signature.html", true, true, "components/ILIAS/Test");
510 $template->setVariable("TXT_DATE", $this->lng->txt("date"));
513 $template->setVariable("VALUE_DATE", ilDatePresentation::formatDate(new ilDate(time(), IL_CAL_UNIX)));
515 $template->setVariable("TXT_SIGNATURE", $this->lng->txt("tst_signature"));
516 $template->setVariable("IMG_SPACER", ilUtil::getImagePath("media/spacer.png"));
517 return $template->get();
518 } else {
519 return "";
520 }
521 }
522
532 public function getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, $overwrite_anonymity = false): string
533 {
534 if (!is_object($testSession)) {
535 throw new InvalidArgumentException('Not an object, expected ilTestSession');
536 }
537 $template = new ilTemplate("tpl.il_as_tst_results_userdata.html", true, true, "components/ILIAS/Test");
538 $user_id = $this->object->_getUserIdFromActiveId($active_id);
539 if (strlen(ilObjUser::_lookupLogin($user_id)) > 0) {
540 $user = new ilObjUser($user_id);
541 } else {
542 $user = new ilObjUser();
543 $user->setLastname($this->lng->txt('deleted_user'));
544 }
545 $t = $testSession->getSubmittedTimestamp();
546 if (!$t) {
547 $t = $this->object->_getLastAccess($testSession->getActiveId());
548 }
549
550 if ($this->getObjectiveOrientedContainer()?->isObjectiveOrientedPresentationRequired()) {
551 $uname = $this->object->userLookupFullName($user_id, $overwrite_anonymity);
552 $template->setCurrentBlock('name');
553 $template->setVariable('TXT_USR_NAME', $this->lng->txt("name"));
554 $template->setVariable('VALUE_USR_NAME', $uname);
555 $template->parseCurrentBlock();
556 }
557
558 $title_matric = "";
559 if (strlen($user->getMatriculation()) && (($this->object->getAnonymity() == false) || ($overwrite_anonymity))) {
560 $template->setCurrentBlock("matriculation");
561 $template->setVariable("TXT_USR_MATRIC", $this->lng->txt("matriculation"));
562 $template->setVariable("VALUE_USR_MATRIC", $user->getMatriculation());
563 $template->parseCurrentBlock();
564 $title_matric = " - " . $this->lng->txt("matriculation") . ": " . $user->getMatriculation();
565 }
566
567 $invited_user = array_pop($this->object->getInvitedUsers($user_id));
568 $title_client = '';
569 $template->setVariable("TXT_TEST_TITLE", $this->lng->txt("title"));
570 $template->setVariable("VALUE_TEST_TITLE", $this->object->getTitle());
571
572 // change the pagetitle (tab title or title in title bar of window)
573 $pagetitle = $this->object->getTitle() . $title_matric . $title_client;
574 $this->tpl->setHeaderPageTitle($pagetitle);
575
576 return $template->get();
577 }
578
588 public function getCorrectSolutionOutput($question_id, $active_id, $pass, ?ilTestQuestionRelatedObjectivesList $objectives_list = null): string
589 {
590 $ilUser = $this->user;
591
592 $test_id = $this->object->getTestId();
593 $question_gui = $this->object->createQuestionGUI("", $question_id);
594
595 $template = new ilTemplate("tpl.il_as_tst_correct_solution_output.html", true, true, "components/ILIAS/Test");
596 $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? true : false;
597 $result_output = $question_gui->getSolutionOutput($active_id, $pass, true, false, $show_question_only, $this->object->getShowSolutionFeedback(), false, false, true);
598 $best_output = $question_gui->getSolutionOutput($active_id, $pass, false, false, $show_question_only, false, true, false, false);
599 if ($this->object->getShowSolutionFeedback() && $this->testrequest->raw('cmd') != 'outCorrectSolution') {
600 $specificAnswerFeedback = $question_gui->getSpecificFeedbackOutput(
601 $question_gui->getObject()->fetchIndexedValuesFromValuePairs(
602 $question_gui->getObject()->getSolutionValues($active_id, $pass)
603 )
604 );
605 if (strlen($specificAnswerFeedback)) {
606 $template->setCurrentBlock("outline_specific_feedback");
607 $template->setVariable("OUTLINE_SPECIFIC_FEEDBACK", $specificAnswerFeedback);
608 $template->parseCurrentBlock();
609 }
610 }
611 $template->setVariable("TEXT_YOUR_SOLUTION", $this->lng->txt("tst_your_answer_was"));
612 $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
613 // I set both old and new since the old one is set as well in several places.
614 $maxpoints = $question_gui->getObject()->getMaximumPoints();
615 if ($maxpoints == 1) {
616 $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->getObject()->getTitleForHTMLOutput()) . " (" . $maxpoints . " " . $this->lng->txt("point") . ")");
617 } else {
618 $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->getObject()->getTitleForHTMLOutput()) . " (" . $maxpoints . " " . $this->lng->txt("points") . ")");
619 }
620 if ($objectives_list !== null) {
621 $objectives = $this->lng->txt('tst_res_lo_objectives_header') . ': ';
622 $objectives .= $objectives_list->getQuestionRelatedObjectiveTitles($question_gui->getObject()->getId());
623 $template->setVariable('OBJECTIVES', $objectives);
624 }
625 $template->setVariable("SOLUTION_OUTPUT", $result_output);
626 $template->setVariable("RECEIVED_POINTS", sprintf($this->lng->txt("you_received_a_of_b_points"), $question_gui->getObject()->getReachedPoints($active_id, $pass), $maxpoints));
627 $template->setVariable("FORMACTION", $this->ctrl->getFormAction($this));
628 $template->setVariable("BACKLINK_TEXT", "&lt;&lt; " . $this->lng->txt("back"));
629 return $template->get();
630 }
631
633 ilTestServiceGUI $target_gui,
634 string $target_cmd
636 return new ilTestPassDetailsOverviewTableGUI($this->ctrl, $target_gui, $target_cmd);
637 }
638
639 protected function isGradingMessageRequired(): bool
640 {
641 $session = $this->test_session_factory->getSession();
642 if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()
643 || $this->object->getScoreSettings()->getScoringSettings()->getPassScoring() === ilObjTest::SCORE_LAST_PASS
644 && $session->getLastFinishedPass() < $session->getLastStartedPass()) {
645 return false;
646 }
647
648 if ($this->object->isShowGradingStatusEnabled()
649 || $this->object->isShowGradingMarkEnabled()) {
650 return true;
651 }
652
653 return false;
654 }
655
656 protected function getGradingMessageBuilder(int $active_id): ilTestGradingMessageBuilder
657 {
659 $this->lng,
660 $this->tpl,
661 $this->object,
662 $this->test_result_repository->getTestResult($active_id)
663 );
664 }
665
667 ilLOTestQuestionAdapter $objectives_adapter,
668 ilTestQuestionSequence $test_sequence
670 $questionRelatedObjectivesList = new ilTestQuestionRelatedObjectivesList();
671
672 $objectives_adapter->buildQuestionRelatedObjectiveList($test_sequence, $questionRelatedObjectivesList);
673
674 return $questionRelatedObjectivesList;
675 }
676
677 protected function populateContent(string $content): void
678 {
679 $this->tpl->setContent($content);
680 }
681
682 protected function outCorrectSolutionCmd(): void
683 {
684 $this->outCorrectSolution(); // cannot be named xxxCmd, because it's also called from context without Cmd in names
685 }
686
687 protected function outCorrectSolution(): void
688 {
689 if (!$this->object->getShowSolutionDetails()) {
690 $this->tpl->setOnScreenMessage('info', $this->lng->txt("no_permission"), true);
691 $this->ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, ilInfoScreenGUI::class]);
692 }
693
694 $testSession = $this->test_session_factory->getSession();
695 $active_id = $testSession->getActiveId();
696
697 if (!($active_id > 0)) {
698 $this->ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, ilInfoScreenGUI::class]);
699 }
700
701 $this->ctrl->saveParameter($this, "pass");
702 $pass = (int) $this->testrequest->raw("pass");
703
704 $active_id = (int) $this->testrequest->raw('evaluation');
705
706 $test_sequence = $this->test_sequence_factory->getSequenceByActiveIdAndPass($active_id, $pass);
707 $test_sequence->loadFromDb();
708 $test_sequence->loadQuestions();
709
710 if (!$test_sequence->questionExists($active_id)) {
711 ilObjTestGUI::accessViolationRedirect();
712 }
713
714 if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
715 $test_sequence = $this->test_sequence_factory->getSequenceByActiveIdAndPass($active_id, $pass);
716 $test_sequence->loadFromDb();
717 $test_sequence->loadQuestions();
718
719 $objectives_adapter = ilLOTestQuestionAdapter::getInstance($testSession);
720 $objectives_list = $this->buildQuestionRelatedObjectivesList($objectives_adapter, $test_sequence);
721 $objectives_list->loadObjectivesTitles();
722 } else {
723 $objectives_list = null;
724 }
725
726 $ilTabs = $this->tabs;
727
728 if ($this instanceof ilTestEvalObjectiveOrientedGUI) {
729 $ilTabs->setBackTarget(
730 $this->lng->txt("tst_back_to_virtual_pass"),
731 $this->ctrl->getLinkTarget($this, 'showVirtualPass')
732 );
733 } else {
734 $ilTabs->setBackTarget(
735 $this->lng->txt("tst_back_to_pass_details"),
736 $this->ctrl->getLinkTarget($this, 'outUserPassDetails')
737 );
738 }
739 $ilTabs->clearSubTabs();
740
741 $this->tpl->setCurrentBlock("ContentStyle");
742 $this->tpl->setVariable("LOCATION_CONTENT_STYLESHEET", ilObjStyleSheet::getContentStylePath(0));
743 $this->tpl->parseCurrentBlock();
744
745 $this->tpl->setCurrentBlock("SyntaxStyle");
746 $this->tpl->setVariable("LOCATION_SYNTAX_STYLESHEET", ilObjStyleSheet::getSyntaxStylePath());
747 $this->tpl->parseCurrentBlock();
748
749 $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css"), "print");
750 if ($this->object->getShowSolutionAnswersOnly()) {
751 $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print_hide_content.css"), "print");
752 }
753
754 $solution = $this->getCorrectSolutionOutput($active_id, $active_id, $pass, $objectives_list);
755
756 $this->tpl->setContent($solution);
757 }
758
759 protected function populatePassFinishDate(ilTemplate $tpl, ?int $pass_finish_date): void
760 {
761 if ($pass_finish_date === null) {
762 return;
763 }
766 $pass_finish_date_string = ilDatePresentation::formatDate(new ilDateTime($pass_finish_date, IL_CAL_UNIX));
768 $tpl->setVariable("PASS_FINISH_DATE_LABEL", $this->lng->txt('tst_pass_finished_on'));
769 $tpl->setVariable("PASS_FINISH_DATE_VALUE", $pass_finish_date_string);
770 }
771
772 protected function populateExamId(ilTemplate $tpl, int $active_id, int $pass): void
773 {
774 if ($this->object->isShowExamIdInTestResultsEnabled()) {
775 $tpl->setVariable('EXAM_ID_TXT', $this->lng->txt('exam_id'));
776 $tpl->setVariable('EXAM_ID', ilObjTest::lookupExamId(
777 $active_id,
778 $pass
779 ));
780 }
781 }
782
783 public function getObject(): ilObjTest
784 {
785 return $this->object;
786 }
787}
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:544
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
Builds data types.
Definition: Factory.php:36
Class Services.
Definition: Services.php:38
const IL_CAL_UNIX
error(string $a_errmsg)
return true
Class ilAccessHandler Checks access for ILIAS objects.
static setUseRelativeDates(bool $a_status)
set use relative dates
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ?ilObjUser $user=null,)
@classDescription Date and time handling
Class for single dates.
Error Handling & global info handling.
Help GUI class.
buildQuestionRelatedObjectiveList(ilTestQuestionSequence $a_test_sequence, ilTestQuestionRelatedObjectivesList $a_objectives_list)
static getInstance(ilTestSession $a_test_session)
language handling
Last visited history for repository items.
static getContentStylePath(int $a_style_id, bool $add_random=true, bool $add_token=true)
get content style path static (to avoid full reading)
static _getResultPass($active_id)
Retrieves the pass number that should be counted for a given user.
static lookupExamId($active_id, $pass)
const SCORE_LAST_PASS
User class.
static _lookupLogin(int $a_user_id)
class ilObjectDataCache
class ilRbacSystem system function like checkAccess, addActiveRole ... Supporting system functions ar...
ILIAS Setting Class.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
special template class to simplify handling of ITX/PEAR
Output class for assessment test evaluation.
Class ilTestPassOverviewTableGUI.
Service GUI class for tests.
readonly ilCtrlInterface $ctrl
ilTestParticipantData $participantData
readonly ResultsPresentationFactory $results_presentation_factory
buildPassDetailsOverviewTableGUI(ilTestServiceGUI $target_gui, string $target_cmd)
readonly ilNavigationHistory $navigation_history
readonly HTTPServices $http
ilTestSequenceFactory $test_sequence_factory
readonly ilErrorHandling $error
buildPassOverviewTableGUI(ilTestEvaluationGUI $target_gui)
readonly Refinery $refinery
readonly ilToolbarGUI $toolbar
readonly TestQuestionsRepository $testquestionsrepository
populateContent(string $content)
ilTestObjectiveOrientedContainer $objective_oriented_container
getCorrectSolutionOutput($question_id, $active_id, $pass, ?ilTestQuestionRelatedObjectivesList $objectives_list=null)
Returns an output of the solution to an answer compared to the correct solution.
readonly ilHelpGUI $help
readonly ilObjUser $user
ilTestParticipantAccessFilterFactory $participant_access_filter
readonly ContentStyle $content_style
setContextResultPresentation(bool $contextResultPresentation)
setParticipantData(ilTestParticipantData $participantData)
buildQuestionRelatedObjectivesList(ilLOTestQuestionAdapter $objectives_adapter, ilTestQuestionSequence $test_sequence)
executeCommand()
execute command
readonly GlobalScreenServices $global_screen
ilTestSessionFactory $test_session_factory
TestResultRepository $test_result_repository
readonly ilComponentRepository $component_repository
readonly ResultsDataFactory $results_data_factory
getResultsSignature()
Returns HTML code for a signature field.
populatePassFinishDate(ilTemplate $tpl, ?int $pass_finish_date)
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.
populateExamId(ilTemplate $tpl, int $active_id, int $pass)
readonly ilDBInterface $db
readonly GeneralQuestionPropertiesRepository $questionrepository
readonly RequestDataCollector $testrequest
ilGlobalTemplateInterface ilTemplate $tpl
sk 2023-08-01: We need this union type, even if it is wrong! To change this
readonly TestLogger $logger
readonly ilSetting $settings
getPassDetailsOverviewTableGUI(array $result_array, int $active_id, int $pass, ilTestServiceGUI $target_gui, string $target_cmd, ?ilTestQuestionRelatedObjectivesList $objectives_list=null, bool $multiple_objectives_involved=true)
readonly ArrayBasedRequestWrapper $post_wrapper
setObjectiveOrientedContainer(ilTestObjectiveOrientedContainer $objective_oriented_container)
readonly ilRbacSystem $rbac_system
readonly ilLanguage $lng
getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, $overwrite_anonymity=false)
Returns the user data for a test results output.
readonly SkillService $skills_service
readonly ilObjectDataCache $obj_cache
getPassOverviewTableData(ilTestSession $test_session, array $passes, bool $with_results)
readonly ilTestShuffler $shuffler
readonly ilTabsGUI $tabs
readonly UIRenderer $ui_renderer
getGradingMessageBuilder(int $active_id)
readonly UIFactory $ui_factory
Service class for tests.
Test session handler.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
static getStyleSheetLocation(string $mode="output", string $a_css_name="")
get full style sheet file name (path inclusive) of current user
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
An entity that renders components to a string output.
Definition: Renderer.php:31
Readable part of repository interface to ilComponentDataDB.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Interface ilDBInterface.
static http()
Fetches the global http state from ILIAS.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
Class ilObjForumAdministration.
global $DIC
Definition: shib_login.php:26
$counter
$objectives