19 declare(strict_types=1);
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'];
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();
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'];
165 $this->service =
new ilTestService($this->
object, $this->db, $this->questionrepository);
167 $this->
lng->loadLanguageModule(
'cert');
168 $this->ref_id = $this->
object->getRefId();
170 $this->test_sequence_factory =
new ilTestSequenceFactory($this->
object, $this->db, $this->questionrepository);
171 $this->objective_oriented_container =
null;
196 ?->isObjectiveOrientedPresentationRequired() ??
false;
198 if ($objective_oriented_presentation) {
199 $consider_hidden_questions =
false;
203 $consider_hidden_questions =
true;
208 foreach ($passes as $pass) {
212 'date' => ilObjTest::lookupLastTestPassAccess($test_session->
getActiveId(), $pass)
214 $considerOptionalQuestions =
true;
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();
221 if ($this->
object->isRandomTest() && !$test_sequence->isAnsweringOptionalQuestionsConfirmed()) {
222 $considerOptionalQuestions =
false;
225 $test_sequence->setConsiderHiddenQuestionsEnabled($consider_hidden_questions);
226 $test_sequence->setConsiderOptionalQuestionsEnabled($considerOptionalQuestions);
229 $objectives_list->loadObjectivesTitles();
231 $row[
'objectives'] = $objectives_list->getUniqueObjectivesStringForQuestions($test_sequence->getUserSequenceQuestions());
234 if (!$with_results) {
239 $result_array = $this->
object->getTestResult(
243 $consider_hidden_questions,
244 $considerOptionalQuestions
247 if (!$result_array[
'pass'][
'total_max_points']) {
248 $row[
'percentage'] = 0;
250 $row[
'percentage'] = ($result_array[
'pass'][
'total_reached_points'] / $result_array[
'pass'][
'total_max_points']) * 100;
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'];
285 $cmd = $this->
ctrl->getCmd();
286 $next_class = $this->
ctrl->getNextClass($this);
288 switch ($next_class) {
290 $ret = &$this->$cmd();
300 $table->setPdfPresentationEnabled(
301 $this->testrequest->isset(
'pdf') && $this->testrequest->raw(
'pdf') == 1
304 $table->setObjectiveOrientedPresentationEnabled(
325 $show_solutions =
false,
326 $only_answered_questions =
false,
327 $show_question_only =
false,
328 $show_reached_points =
false,
331 ?ResultsTitlesBuilder $testResultHeaderLabelBuilder =
null 333 $maintemplate =
new ilTemplate(
'tpl.il_as_tst_list_of_answers.html',
true,
true,
'components/ILIAS/Test');
337 foreach ($result_array as $question_data) {
338 if (!array_key_exists(
'workedthrough', $question_data)) {
339 $question_data[
'workedthrough'] = 0;
341 if (!array_key_exists(
'qid', $question_data)) {
342 $question_data[
'qid'] = -1;
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);
354 $question_gui->getObject()->setShuffler($this->shuffler->getAnswerShuffleFor(
359 if (is_object($question_gui)) {
361 $template->setCurrentBlock(
'block_id');
362 $template->setVariable(
'BLOCK_ID',
"detailed_answer_block_act_{$active_id}_qst_{$question_id}");
363 $template->parseCurrentBlock();
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();
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();
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()));
381 if ($objectives_list !== null) {
382 $objectives = $this->
lng->txt(
'tst_res_lo_objectives_header') .
': ';
383 $objectives .= $objectives_list->getQuestionRelatedObjectiveTitles($question_gui->getObject()->getId());
387 $show_question_only = ($this->
object->getShowSolutionAnswersOnly()) ?
true :
false;
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'));
399 $compare_template->setVariable(
"HEADER_PARTICIPANT", $this->
lng->txt(
'tst_header_participant_no_answer'));
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);
406 $compare_template->setVariable(
'PARTICIPANT', $result_output);
407 $compare_template->setVariable(
'SOLUTION', $best_output);
408 $template->setVariable(
'SOLUTION_OUTPUT', $compare_template->get());
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);
414 $maintemplate->setCurrentBlock(
'printview_question');
415 $maintemplate->setVariable(
"QUESTION_PRINTVIEW", $template->get());
416 $maintemplate->parseCurrentBlock();
423 if ($testResultHeaderLabelBuilder !==
null) {
424 if ($pass !==
null) {
425 $headerText = $testResultHeaderLabelBuilder->getListOfAnswersHeaderLabel($pass + 1);
427 $headerText = $testResultHeaderLabelBuilder->getVirtualListOfAnswersHeaderLabel();
433 $maintemplate->setVariable(
'RESULTS_OVERVIEW', $headerText);
434 return $maintemplate->get();
444 bool $multiple_objectives_involved =
true 446 $this->
ctrl->setParameter($target_gui,
'active_id', $active_id);
447 $this->
ctrl->setParameter($target_gui,
'pass', $pass);
451 if ($objectives_list !==
null) {
452 $table_gui->setQuestionRelatedObjectivesList($objectives_list);
453 $table_gui->setObjectiveOrientedPresentationEnabled(
true);
456 $table_gui->setMultipleObjectivesInvolved($multiple_objectives_involved);
458 $table_gui->setActiveId($active_id);
459 $table_gui->setShowSuggestedSolution(
false);
461 $users_question_solutions = [];
463 foreach ($result_array as $key => $val) {
464 if ($key ===
'test' || $key ===
'pass') {
468 if ($this->
object->getShowSolutionSuggested() && strlen($val[
'solution'])) {
469 $table_gui->setShowSuggestedSolution(
true);
472 if (isset($val[
'pass'])) {
473 $table_gui->setPassColumnEnabled(
true);
476 $users_question_solutions[$key] = $val;
479 $table_gui->initColumns();
481 $table_gui->setFilterCommand($target_cmd .
'SetTableFilter');
482 $table_gui->setResetCommand($target_cmd .
'ResetTableFilter');
484 $table_gui->setData($users_question_solutions);
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"));
504 $template->setVariable(
"TXT_SIGNATURE", $this->
lng->txt(
"tst_signature"));
506 return $template->get();
523 if (!is_object($testSession)) {
526 $template =
new ilTemplate(
"tpl.il_as_tst_results_userdata.html",
true,
true,
"components/ILIAS/Test");
527 $user_id = $this->
object->_getUserIdFromActiveId($active_id);
532 $user->setLastname($this->
lng->txt(
'deleted_user'));
534 $t = $testSession->getSubmittedTimestamp();
536 $t = $this->
object->_getLastAccess($testSession->getActiveId());
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();
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();
556 $invited_user = array_pop($this->
object->getInvitedUsers(
$user_id));
558 $template->setVariable(
"TXT_TEST_TITLE", $this->
lng->txt(
"title"));
559 $template->setVariable(
"VALUE_TEST_TITLE", $this->
object->getTitle());
562 $pagetitle = $this->
object->getTitle() . $title_matric . $title_client;
563 $this->tpl->setHeaderPageTitle($pagetitle);
565 return $template->get();
581 $test_id = $this->
object->getTestId();
582 $question_gui = $this->
object->createQuestionGUI(
"", $question_id);
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)
594 if (strlen($specificAnswerFeedback)) {
595 $template->setCurrentBlock(
"outline_specific_feedback");
596 $template->setVariable(
"OUTLINE_SPECIFIC_FEEDBACK", $specificAnswerFeedback);
597 $template->parseCurrentBlock();
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"));
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") .
")");
607 $template->setVariable(
"QUESTION_TITLE", $this->
object->getQuestionTitle($question_gui->getObject()->getTitleForHTMLOutput()) .
" (" . $maxpoints .
" " . $this->
lng->txt(
"points") .
")");
609 if ($objectives_list !==
null) {
610 $objectives = $this->
lng->txt(
'tst_res_lo_objectives_header') .
': ';
611 $objectives .= $objectives_list->getQuestionRelatedObjectiveTitles($question_gui->getObject()->getId());
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",
"<< " . $this->
lng->txt(
"back"));
618 return $template->get();
630 $session = $this->test_session_factory->getSession();
633 && $session->getLastFinishedPass() < $session->getLastStartedPass()) {
637 if ($this->
object->isShowGradingStatusEnabled()
638 || $this->
object->isShowGradingMarkEnabled()) {
651 $this->test_result_repository->getTestResult($active_id)
663 return $questionRelatedObjectivesList;
668 $this->tpl->setContent($content);
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]);
683 $testSession = $this->test_session_factory->getSession();
684 $active_id = $testSession->getActiveId();
686 if (!($active_id > 0)) {
687 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, ilInfoScreenGUI::class]);
690 $this->
ctrl->saveParameter($this,
"pass");
691 $pass = (
int) $this->testrequest->raw(
"pass");
693 $active_id = (
int) $this->testrequest->raw(
'evaluation');
695 $test_sequence = $this->test_sequence_factory->getSequenceByActiveIdAndPass($active_id, $pass);
696 $test_sequence->loadFromDb();
697 $test_sequence->loadQuestions();
699 if (!$test_sequence->questionExists($active_id)) {
700 ilObjTestGUI::accessViolationRedirect();
704 $test_sequence = $this->test_sequence_factory->getSequenceByActiveIdAndPass($active_id, $pass);
705 $test_sequence->loadFromDb();
706 $test_sequence->loadQuestions();
710 $objectives_list->loadObjectivesTitles();
712 $objectives_list =
null;
719 $this->
lng->txt(
"tst_back_to_virtual_pass"),
720 $this->
ctrl->getLinkTarget($this,
'showVirtualPass')
723 $ilTabs->setBackTarget(
724 $this->
lng->txt(
"tst_back_to_pass_details"),
725 $this->
ctrl->getLinkTarget($this,
'outUserPassDetails')
728 $ilTabs->clearSubTabs();
730 $this->tpl->setCurrentBlock(
"ContentStyle");
732 $this->tpl->parseCurrentBlock();
734 $this->tpl->setCurrentBlock(
"SyntaxStyle");
736 $this->tpl->parseCurrentBlock();
739 if ($this->
object->getShowSolutionAnswersOnly()) {
745 $this->tpl->setContent($solution);
750 if ($pass_finish_date ===
null) {
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);
763 if ($this->
object->isShowExamIdInTestResultsEnabled()) {
774 return $this->object;
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.
isContextResultPresentation()
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)
getObjectiveOrientedContainer()
ilGlobalTemplateInterface ilTemplate $tpl
sk 2023-08-01: We need this union type, even if it is wrong! To change this
setContextResultPresentation(bool $contextResultPresentation)
readonly GeneralQuestionPropertiesRepository $questionrepository
getResultsSignature()
Returns HTML code for a signature field.
readonly ArrayBasedRequestWrapper $post_wrapper
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
static useRelativeDates()
readonly ResultsDataFactory $results_data_factory
isGradingMessageRequired()
readonly ilComponentRepository $component_repository
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
TestResultRepository $test_result_repository
setParticipantData(ilTestParticipantData $participantData)
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.
readonly UIRenderer $ui_renderer
getGradingMessageBuilder(int $active_id)
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.
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.
static getSyntaxStylePath()
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
readonly UIFactory $ui_factory
bool $contextResultPresentation
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...
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)
Class ArrayBasedRequestWrapper.
static _lookupLogin(int $a_user_id)