19 declare(strict_types=1);
78 $cmd = $this->
ctrl->getCmd();
79 $next_class = $this->
ctrl->getNextClass($this);
80 $this->
ctrl->saveParameter($this,
"sequence");
81 $this->
ctrl->saveParameter($this,
"active_id");
83 switch ($next_class) {
84 case 'iltestpassdetailsoverviewtablegui':
86 $this->
ctrl->forwardCommand($tableGUI);
90 if (in_array($cmd, [
'excel_scored_test_run',
'excel_all_test_runs',
'csv'])) {
92 } elseif (in_array($cmd, [
'excel_all_test_runs_a',
'csv_a'])) {
108 ilObjTestGUI::accessViolationRedirect();
112 $table_gui->writeFilterToSession();
113 $this->
ctrl->redirect($this,
"outEvaluation");
122 ilObjTestGUI::accessViolationRedirect();
126 $table_gui->resetFilter();
127 $this->
ctrl->redirect($this,
"outEvaluation");
133 public function outEvaluation(?array $prior_components = null):
void 138 ilObjTestGUI::accessViolationRedirect();
147 $this->
object->getAnonymity(),
148 $this->
object->isOfferingQuestionHintsEnabled()
154 foreach ($table_gui->getFilterItems() as $item) {
155 if (!in_array($item->getValue(), [
false,
''])) {
156 switch ($item->getPostVar()) {
160 $filter_array[$item->getPostVar()] = $item->getValue();
163 $passedonly = $item->getChecked();
173 $eval = $factory->getEvaluationData();
175 $eval->setFilterArray($filter_array);
176 $found_participants = $eval->getParticipants();
182 $this->participant_access_filter->getAccessStatisticsUserFilter($this->ref_id)
190 if (!isset($found_participants[$active_id]) || !($found_participants[$active_id] instanceof
ilTestEvaluationUserData)) {
195 $userdata = $found_participants[$active_id];
199 $mark_obj = $this->
object->getMarkSchema()->getMatchingMark($userdata->getReachedPointsInPercent());
201 if ($mark_obj->getPassed() ==
false || !$userdata->areObligationsAnswered()) {
208 if ($this->
object->getAnonymity()) {
209 $evaluationrow[
'name'] = $counter;
210 $evaluationrow[
'login'] =
'';
212 $evaluationrow[
'name'] = $userdata->getName();
213 if (strlen($userdata->getLogin())) {
214 $evaluationrow[
'login'] =
"[" . $userdata->getLogin() .
"]";
216 $evaluationrow[
'login'] =
'';
220 $evaluationrow[
'reached'] = $userdata->getReached();
221 $evaluationrow[
'max'] = $userdata->getMaxpoints();
222 $evaluationrow[
'hint_count'] = $userdata->getRequestedHintsCountFromScoredPass();
223 $evaluationrow[
'exam_id'] = $userdata->getExamIdFromScoredPass();
224 $percentage = $userdata->getReachedPointsInPercent();
225 $mark = $this->
object->getMarkSchema()->getMatchingMark($percentage);
226 if (is_object($mark)) {
227 $evaluationrow[
'mark'] = $mark->getShortName();
229 $evaluationrow[
'answered'] = $userdata->getQuestionsWorkedThroughInPercent();
230 $evaluationrow[
'questions_worked_through'] = $userdata->getQuestionsWorkedThrough();
231 $evaluationrow[
'number_of_questions'] = $userdata->getNumberOfQuestions();
232 $time_seconds = $userdata->getTimeOfWork();
233 $time_hours = floor($time_seconds / 3600);
234 $time_seconds -= $time_hours * 3600;
235 $time_minutes = floor($time_seconds / 60);
236 $time_seconds -= $time_minutes * 60;
237 $evaluationrow[
'working_time'] = sprintf(
"%02d:%02d:%02d", $time_hours, $time_minutes, $time_seconds);
238 $this->
ctrl->setParameter($this,
"active_id", $active_id);
239 $href = $this->
ctrl->getLinkTarget($this,
"detailedEvaluation");
240 $detailed_evaluation = $this->
lng->txt(
"detailed_evaluation_show");
241 $evaluationrow[
'details'] =
"<a class=\"il_ContainerItemCommand\" href=\"$href\">$detailed_evaluation</a>";
243 if ($userdata->getUserID() !== null) {
246 $evaluationrow[
'email'] = $userfields[
'email'] ??
'';
247 $evaluationrow[
'institution'] = $userfields[
'institution'] ??
'';
248 $evaluationrow[
'street'] = $userfields[
'street'] ??
'';
249 $evaluationrow[
'city'] = $userfields[
'city'] ??
'';
250 $evaluationrow[
'zipcode'] = $userfields[
'zipcode'] ??
'';
251 $evaluationrow[
'country'] = $userfields[
'country'] ??
'';
252 $evaluationrow[
'sel_country'] = $userfields[
'sel_country'] ??
'';
253 $evaluationrow[
'department'] = $userfields[
'department'] ??
'';
254 $evaluationrow[
'matriculation'] = $userfields[
'matriculation'] ??
'';
256 $data[] = $evaluationrow;
263 $ilToolbar->setFormName(
'form_output_eval');
264 $ilToolbar->setFormAction($this->
ctrl->getFormAction($this,
'exportEvaluation'));
268 $this->ui_factory->button()->shy($this->
lng->txt(
'exp_grammar_as') .
' ' . $this->
lng->txt(
'exp_type_excel') .
' (' . $this->
lng->txt(
'exp_scored_test_run') .
')', $this->
ctrl->getLinkTarget($this,
'excel_scored_test_run')),
269 $this->ui_factory->button()->shy($this->
lng->txt(
'exp_grammar_as') .
' ' . $this->
lng->txt(
'exp_type_excel') .
' (' . $this->
lng->txt(
'exp_all_test_runs') .
')', $this->
ctrl->getLinkTarget($this,
'excel_all_test_runs')),
270 $this->ui_factory->button()->shy($this->
lng->txt(
'exp_grammar_as') .
' ' . $this->
lng->txt(
'exp_type_spss'), $this->
ctrl->getLinkTarget($this,
'csv'))
274 $this->ui_factory->button()->shy($this->
lng->txt(
'exp_grammar_as') .
' ' . $this->
lng->txt(
'exp_type_excel') .
' (' . $this->
lng->txt(
'exp_all_test_runs') .
')', $this->
ctrl->getLinkTarget($this,
'excel_all_test_runs')),
275 $this->ui_factory->button()->shy($this->
lng->txt(
'exp_grammar_as') .
' ' . $this->
lng->txt(
'exp_type_spss'), $this->
ctrl->getLinkTarget($this,
'csv'))
279 if (!$this->
object->getAnonymity()) {
282 if ($globalCertificatePrerequisites->validate()) {
283 $options[] = $this->ui_factory->button()->shy($this->
lng->txt(
'exp_grammar_as') .
' ' . $this->
lng->txt(
'exp_type_certificate'), $this->
ctrl->getLinkTarget($this,
'exportCertificateArchive'));
289 $select = $this->ui_factory->dropdown()->standard($options)->withLabel($this->
lng->txt(
'exp_eval_data'));
290 $ilToolbar->addComponent($select);
295 $this->tpl->setContent($this->ui_renderer->render(
296 array_filter(array_merge(
297 $prior_components ?? [],
298 [$this->ui_factory->legacy($table_gui->getHTML())]
306 ilObjTestGUI::accessViolationRedirect();
311 $active_id = $this->testrequest->int(
'active_id');
313 if (!$this->
getTestAccess()->checkResultsAccessForActiveId($active_id)) {
314 ilObjTestGUI::accessViolationRedirect();
317 if ($active_id === null) {
318 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'detailed_evaluation_missing_active_id'),
true);
319 $this->
ctrl->redirect($this,
'outEvaluation');
324 $backBtn = $this->ui_factory->button()->standard($this->
lng->txt(
'back'), $this->
ctrl->getLinkTarget($this,
'outEvaluation'));
325 $this->
toolbar->addComponent($backBtn);
327 $this->
object->setAccessFilteredParticipantList(
328 $this->
object->buildStatisticsAccessFilteredParticipantList()
331 $data = $this->
object->getCompleteEvaluationData();
334 $form->setTitle(sprintf(
335 $this->
lng->txt(
'detailed_evaluation_for'),
336 $data->getParticipant($active_id)->getName()
340 $resultPoints->setValue(
$data->getParticipant($active_id)->getReached() .
" " . strtolower($this->
lng->txt(
"of")) .
" " .
$data->getParticipant($active_id)->getMaxpoints() .
" (" . sprintf(
"%2.2f",
$data->getParticipant($active_id)->getReachedPointsInPercent()) .
" %" .
")");
341 $form->addItem($resultPoints);
343 if (strlen(
$data->getParticipant($active_id)->getMark())) {
345 $resultMarks->setValue(
$data->getParticipant($active_id)->getMark());
346 $form->addItem($resultMarks);
349 if ($this->
object->isOfferingQuestionHintsEnabled()) {
351 $requestHints->setValue(
$data->getParticipant($active_id)->getRequestedHintsCountFromScoredPass());
352 $form->addItem($requestHints);
355 $time_seconds =
$data->getParticipant($active_id)->getTimeOfWork();
356 $atime_seconds =
$data->getParticipant($active_id)->getNumberOfQuestions() ? $time_seconds /
$data->getParticipant($active_id)->getNumberOfQuestions() : 0;
357 $time_hours = floor($time_seconds / 3600);
358 $time_seconds -= $time_hours * 3600;
359 $time_minutes = floor($time_seconds / 60);
360 $time_seconds -= $time_minutes * 60;
362 $timeOfWork->setValue(sprintf(
"%02d:%02d:%02d", $time_hours, $time_minutes, $time_seconds));
363 $form->addItem($timeOfWork);
365 $this->tpl->setVariable(
"TXT_ATIMEOFWORK", $this->
lng->txt(
""));
366 $time_hours = floor($atime_seconds / 3600);
367 $atime_seconds -= $time_hours * 3600;
368 $time_minutes = floor($atime_seconds / 60);
369 $atime_seconds -= $time_minutes * 60;
371 $avgTimeOfWork->setValue(sprintf(
"%02d:%02d:%02d", $time_hours, $time_minutes, $atime_seconds));
372 $form->addItem($avgTimeOfWork);
376 $form->addItem($firstVisit);
380 $form->addItem($lastVisit);
383 $nrPasses->setValue(
$data->getParticipant($active_id)->getLastPass() + 1);
384 $form->addItem($nrPasses);
388 $scoredPass->setValue(
$data->getParticipant($active_id)->getBestPass() + 1);
390 $scoredPass->setValue(
$data->getParticipant($active_id)->getLastPass() + 1);
392 $form->addItem($scoredPass);
394 $median =
$data->getStatistics()->getStatistics()->median();
395 $pct =
$data->getParticipant($active_id)->getMaxpoints() ? ($median /
$data->getParticipant($active_id)->getMaxpoints()) * 100.0 : 0;
396 $mark = $this->
object->getMarkSchema()->getMatchingMark($pct);
397 if (is_object($mark)) {
399 $markMedian->setValue($mark->getShortName());
400 $form->addItem($markMedian);
404 $rankParticipant->setValue(
$data->getStatistics()->getStatistics()->rank(
$data->getParticipant($active_id)->getReached()));
405 $form->addItem($rankParticipant);
408 $rankMedian->setValue(
$data->getStatistics()->getStatistics()->rank_median());
409 $form->addItem($rankMedian);
412 $totalParticipants->setValue(
$data->getStatistics()->getStatistics()->count());
413 $form->addItem($totalParticipants);
416 $medianField->setValue($median);
417 $form->addItem($medianField);
419 $this->tpl->setContent($form->getHTML());
423 for ($pass = 0; $pass <=
$data->getParticipant($active_id)->getLastPass(); $pass++) {
425 if ($finishdate > 0) {
426 if (($this->testAccess->getAccess()->checkAccess(
'write',
'', $this->testrequest->getRefId()))) {
427 $this->
ctrl->setParameter($this,
'statistics',
'1');
428 $this->
ctrl->setParameter($this,
'active_id', $active_id);
429 $this->
ctrl->setParameter($this,
'pass', $pass);
431 $this->
ctrl->setParameter($this,
'statistics',
'');
432 $this->
ctrl->setParameter($this,
'active_id',
'');
433 $this->
ctrl->setParameter($this,
'pass',
'');
437 $table->
setTitle(sprintf($this->
lng->txt(
"tst_eval_question_points"), $pass + 1));
438 if (($this->testAccess->getAccess()->checkAccess(
'write',
'', $this->testrequest->getRefId()))) {
439 $button_show_answer = $this->ui_renderer->render(
440 $this->ui_factory->button()->standard(
441 $this->
lng->txt(
'tst_show_answer_sheet'),
442 $this->
ctrl->getLinkTarget($this,
'outParticipantsPassDetails'),
447 $questions =
$data->getParticipant($active_id)->getQuestions($pass);
448 if (!is_array($questions)) {
449 $questions =
$data->getParticipant($active_id)->getQuestions(0);
455 foreach ((array) $questions as $question) {
456 $userDataData = array(
457 'counter' => ++$counter,
458 'id' => $question[
'id'],
459 'id_txt' => $this->
lng->txt(
'question_id_short'),
460 'title' => htmlspecialchars(
$data->getQuestionTitle($question[
'id']))
463 $answeredquestion =
$data->getParticipant($active_id)->getPass($pass)->getAnsweredQuestionByQuestionId($question[
"id"]);
464 if (is_array($answeredquestion)) {
465 $percent = $answeredquestion[
'points'] ? $answeredquestion[
'reached'] / $answeredquestion[
'points'] * 100.0 : 0;
466 $userDataData[
'points'] = $answeredquestion[
'reached'] .
' ' . strtolower($this->
lng->txt(
'of')) .
" " . $answeredquestion[
'points'] .
' (' . sprintf(
"%.2f", $percent) .
' %)';
468 $userDataData[
'points'] =
'0 ' . strtolower($this->
lng->txt(
'of')) .
' ' . $question[
'points'] .
' (' . sprintf(
"%.2f", 0) .
' %) - ' . $this->
lng->txt(
'question_not_answered');
471 $tableData[] = $userDataData;
473 $table->setData($tableData);
475 $tables[] = $table->getHTML() . ($button_show_answer ??
'');
479 $this->tpl->setContent($form->getHTML() . implode(
'', $tables));
488 $question_id = $this->testrequest->int(
'qid');
503 $question_object->deliverFileUploadZIPFile(
505 $this->
object->getTestId(),
506 $this->
object->getTitle()
509 $this->
ctrl->redirect($this,
"singleResults");
519 ilObjTestGUI::accessViolationRedirect();
524 $this->tpl->addBlockFile(
"ADM_CONTENT",
"adm_content",
"tpl.il_as_tst_eval_anonymous_aggregation.html",
"Modules/Test");
526 $this->
object->setAccessFilteredParticipantList(
527 $this->
object->buildStatisticsAccessFilteredParticipantList()
530 $eval = $this->
object->getCompleteEvaluationData();
532 $found_participants = $eval->getParticipants();
533 if (count($found_participants)) {
535 $this->ui_factory->button()->shy($this->
lng->txt(
'exp_type_excel'), $this->
ctrl->getLinkTarget($this,
'excel_all_test_runs_a')),
536 $this->ui_factory->button()->shy($this->
lng->txt(
'exp_type_spss'), $this->
ctrl->getLinkTarget($this,
'csv_a'))
539 $select = $this->ui_factory->dropdown()->standard($options)->withLabel($this->
lng->txt(
'exp_eval_data'));
540 $this->
toolbar->addComponent($select);
543 'result' => $this->
lng->txt(
"tst_eval_total_persons"),
544 'value' => count($found_participants)
546 $total_finished = $eval->getTotalFinishedParticipants();
548 'result' => $this->
lng->txt(
"tst_eval_total_finished"),
549 'value' => $total_finished
551 $average_time = $this->
object->evalTotalStartedAverageTime(
552 $eval->getParticipantIds()
554 $diff_seconds = $average_time;
555 $diff_hours = floor($diff_seconds / 3600);
556 $diff_seconds -= $diff_hours * 3600;
557 $diff_minutes = floor($diff_seconds / 60);
558 $diff_seconds -= $diff_minutes * 60;
559 array_push(
$data, array(
560 'result' => $this->
lng->txt(
"tst_eval_total_finished_average_time"),
561 'value' => sprintf(
"%02d:%02d:%02d", $diff_hours, $diff_minutes, $diff_seconds)
564 $total_passed_reached = 0;
565 $total_passed_max = 0;
566 $total_passed_time = 0;
567 foreach ($found_participants as $userdata) {
568 if ($userdata->getPassed()) {
570 $total_passed_reached += $userdata->getReached();
571 $total_passed_max += $userdata->getMaxpoints();
572 $total_passed_time += $userdata->getTimeOfWork();
575 $average_passed_reached = $total_passed ? $total_passed_reached / $total_passed : 0;
576 $average_passed_max = $total_passed ? $total_passed_max / $total_passed : 0;
577 $average_passed_time = $total_passed ? $total_passed_time / $total_passed : 0;
578 array_push(
$data, array(
579 'result' => $this->
lng->txt(
"tst_eval_total_passed"),
580 'value' => $total_passed
582 array_push(
$data, array(
583 'result' => $this->
lng->txt(
"tst_eval_total_passed_average_points"),
584 'value' => sprintf(
"%2.2f", $average_passed_reached) .
" " . strtolower($this->
lng->txt(
"of")) .
" " . sprintf(
"%2.2f", $average_passed_max)
586 $average_time = $average_passed_time;
587 $diff_seconds = $average_time;
588 $diff_hours = floor($diff_seconds / 3600);
589 $diff_seconds -= $diff_hours * 3600;
590 $diff_minutes = floor($diff_seconds / 60);
591 $diff_seconds -= $diff_minutes * 60;
592 array_push(
$data, array(
593 'result' => $this->
lng->txt(
"tst_eval_total_passed_average_time"),
594 'value' => sprintf(
"%02d:%02d:%02d", $diff_hours, $diff_minutes, $diff_seconds)
599 $table_gui->setData(
$data);
600 $this->tpl->setVariable(
'AGGREGATED_RESULTS', $table_gui->getHTML());
604 foreach ($eval->getQuestionTitles() as $question_id => $question_title) {
608 foreach ($found_participants as $userdata) {
609 for ($i = 0; $i <= $userdata->getLastPass(); $i++) {
610 if (is_object($userdata->getPass($i))) {
611 $question = $userdata->getPass($i)->getAnsweredQuestionByQuestionId($question_id);
612 if (is_array($question)) {
614 $reached += $question[
"reached"];
615 $max += $question[
"points"];
620 $percent = $max ? $reached / $max * 100.0 : 0;
622 $this->
ctrl->setParameter($this,
"qid", $question_id);
624 $points_reached = ($answered ? $reached / $answered : 0);
625 $points_max = ($answered ? $max / $answered : 0);
629 'qid' => $question_id,
630 'title' => htmlspecialchars($question_title),
631 'points' => $points_reached,
632 'points_reached' => $points_reached,
633 'points_max' => $points_max,
634 'percentage' => (
float) $percent,
635 'answers' => $answered
640 $table_gui->setData($rows);
641 $this->tpl->setVariable(
'TBL_AVG_REACHED', $table_gui->getHTML());
647 if ($this->testrequest->isset(
"g_filterby")) {
648 $filterby = $this->testrequest->raw(
"g_filterby");
652 if ($this->testrequest->isset(
"g_userfilter")) {
653 $filtertext = $this->testrequest->raw(
"g_userfilter");
657 if ($this->testrequest->isset(
"g_passedonly")) {
658 if ($this->testrequest->raw(
"g_passedonly") == 1) {
664 $cmd = $this->testrequest->raw(
"export_type");
667 case "excel_scored_test_run":
668 (
new ilExcelTestExport($this->
object, $filterby, $filtertext, $passedonly,
true))
671 ->deliver($this->
object->getTitle() .
'_results');
675 (
new ilCSVTestExport($this->
object, $filterby, $filtertext, $passedonly))
677 ->deliver($this->
object->getTitle() .
'_results');
680 case "excel_all_test_runs":
681 (
new ilExcelTestExport($this->
object, $filterby, $filtertext, $passedonly,
false))
684 ->deliver($this->
object->getTitle() .
'_results');
688 $this->
ctrl->setParameterByClass(
"iltestcertificategui",
"g_passedonly",
"1");
690 if (strlen($filtertext)) {
691 $this->
ctrl->setParameterByClass(
"iltestcertificategui",
"g_userfilter", $filtertext);
693 $this->
ctrl->redirect($this,
"exportCertificateArchive");
701 case "excel_all_test_runs_a":
703 ->withAggregatedResultsPage()
704 ->deliver($this->
object->getTitle() .
'_aggregated');
708 ->withAggregatedResults()
709 ->deliver($this->
object->getTitle() .
'_aggregated');
717 if (!$globalCertificatePrerequisites->validate()) {
718 $this->error->raiseError($this->
lng->txt(
'permission_denied'), $this->error->MESSAGE);
722 $logger = $this->logging_services->root();
725 $objectId = $this->
object->getId();
728 $pathFactory->create($this->object)
733 $this->
object->setAccessFilteredParticipantList(
734 $this->
object->buildStatisticsAccessFilteredParticipantList()
740 $total_users = $this->
object->evalTotalPersonsArray();
741 if (count($total_users) === 0) {
742 $this->outEvaluation([
743 $this->ui_factory->messageBox()->info(
744 $this->
lng->txt(
'export_cert_no_users')
753 $ignored_usr_ids = [];
754 $failed_pdf_generation_usr_ids = [];
755 foreach ($total_users as $active_id => $name) {
758 if (!$certValidator->isCertificateDownloadable($user_id, $objectId)) {
759 $this->logging_services->root()->debug(
761 'No certificate available for user %s in test %s ' .
762 '(Check if: ilServer is enabled / Certificates are enabled globally / ' .
763 'A Certificate is issued for the user)',
768 $ignored_usr_ids[] = $user_id;
775 $this->
lng->txt(
'error_creating_certificate_pdf')
778 $pdf = $pdfAction->
createPDF($user_id, $objectId);
780 $zipAction->addPDFtoArchiveDirectory($pdf, $archive_dir, $user_id .
"_" . str_replace(
787 $this->logging_services->root()->error(
789 'The certificate service could not create a PDF for user %s and test %s',
794 $failed_pdf_generation_usr_ids[] = $user_id;
802 $zipAction->zipCertificatesInArchiveDirectory($archive_dir,
true);
804 $this->logging_services->root()->error($e->getMessage());
805 $this->logging_services->root()->error($e->getTraceAsString());
806 $components[] = $this->ui_factory->messageBox()->failure(
807 $this->
lng->txt(
'error_creating_certificate_zip_empty')
812 if ($ignored_usr_ids !== []) {
813 $user_logins = array_map(
817 if (count($ignored_usr_ids) === 1) {
818 $components[] = $this->ui_factory->messageBox()->info(sprintf(
819 $this->
lng->txt(
'export_cert_ignored_for_users_s'),
820 implode(
', ', $user_logins)
823 $components[] = $this->ui_factory->messageBox()->info(sprintf(
824 $this->
lng->txt(
'export_cert_ignored_for_users_p'),
825 count($ignored_usr_ids),
826 implode(
', ', $user_logins)
831 if ($failed_pdf_generation_usr_ids !== []) {
832 $user_logins = array_map(
834 $failed_pdf_generation_usr_ids
836 if (count($failed_pdf_generation_usr_ids) === 1) {
837 $components[] = $this->ui_factory->messageBox()->info(sprintf(
838 $this->
lng->txt(
'export_cert_failed_for_users_s'),
839 implode(
', ', $user_logins)
842 $components[] = $this->ui_factory->messageBox()->info(sprintf(
843 $this->
lng->txt(
'export_cert_failed_for_users_p'),
844 count($ignored_usr_ids),
845 implode(
', ', $user_logins)
850 $this->outEvaluation($components);
861 if ($original_id > 0) {
875 $active_id = (
int) $this->testrequest->raw(
"active_id");
877 if (!$this->
getTestAccess()->checkResultsAccessForActiveId($active_id)) {
878 ilObjTestGUI::accessViolationRedirect();
881 $this->
ctrl->saveParameter($this,
"active_id");
882 $testSession = $this->testSessionFactory->getSession($active_id);
885 if ($testSession->getTestId() != $this->
object->getTestId()) {
886 ilObjTestGUI::accessViolationRedirect();
889 $this->
ctrl->saveParameter($this,
"pass");
890 $pass = (
int) $this->testrequest->raw(
"pass");
892 if ($this->testrequest->isset(
'statistics') && $this->testrequest->raw(
'statistics') == 1) {
893 $this->
ctrl->setParameterByClass(
"ilTestEvaluationGUI",
"active_id", $active_id);
894 $this->
ctrl->saveParameter($this,
'statistics');
896 $ilTabs->setBackTarget(
897 $this->
lng->txt(
'back'),
898 $this->
ctrl->getLinkTargetByClass(
'ilTestEvaluationGUI',
'detailedEvaluation')
900 } elseif ($this->
object->getNrOfTries() == 1) {
901 $ilTabs->setBackTarget(
902 $this->
lng->txt(
'back'),
903 $this->
ctrl->getLinkTargetByClass(
'ilParticipantsTestResultsGUI')
906 $ilTabs->setBackTarget(
907 $this->
lng->txt(
'tst_results_back_overview'),
908 $this->
ctrl->getLinkTarget($this,
'outParticipantsResultsOverview')
912 if ($this->testrequest->isset(
'show_best_solutions')) {
914 } elseif ($this->testrequest->isset(
'hide_best_solutions')) {
916 } elseif (
ilSession::get(
'tst_results_show_best_solutions') !== null) {
920 $template =
new ilTemplate(
"tpl.il_as_tst_pass_details_overview_participants.html",
true,
true,
"Modules/Test");
926 $this->
ctrl->setParameter($this,
'hide_best_solutions',
'1');
927 $toolbar->setHideBestSolutionsLinkTarget($this->
ctrl->getLinkTarget($this,
'outParticipantsPassDetails'));
928 $this->
ctrl->setParameter($this,
'hide_best_solutions',
'');
930 $this->
ctrl->setParameter($this,
'show_best_solutions',
'1');
931 $toolbar->setShowBestSolutionsLinkTarget($this->
ctrl->getLinkTarget($this,
'outParticipantsPassDetails'));
932 $this->
ctrl->setParameter($this,
'show_best_solutions',
'');
936 $template->setVariable(
'RESULTS_TOOLBAR', $this->
ctrl->getHTML(
$toolbar));
940 $gradingMessageBuilder->buildList();
942 $template->setCurrentBlock(
'grading_message');
943 $template->setVariable(
'GRADING_MESSAGE', $gradingMessageBuilder->getList());
944 $template->parseCurrentBlock();
947 $pass_results = $this->results_factory->getPassResultsFor(
954 $table = $this->results_presentation_factory->getPassResultsPresentationTable(
960 $this->tpl->setVariable(
970 if ($this->
object->getShowSolutionAnswersOnly()) {
981 if ($this->testrequest->isset(
'show_best_solutions')) {
983 } elseif ($this->testrequest->isset(
'hide_best_solutions')) {
985 } elseif (
ilSession::get(
'tst_results_show_best_solutions') !== null) {
989 $this->
ctrl->setParameter($this,
'hide_best_solutions',
'1');
990 $toolbar->setHideBestSolutionsLinkTarget($this->
ctrl->getLinkTarget($this,
'multiParticipantsPassDetails'));
991 $this->
ctrl->setParameter($this,
'hide_best_solutions',
'');
993 $this->
ctrl->setParameter($this,
'show_best_solutions',
'1');
994 $toolbar->setShowBestSolutionsLinkTarget($this->
ctrl->getLinkTarget($this,
'multiParticipantsPassDetails'));
995 $this->
ctrl->setParameter($this,
'show_best_solutions',
'');
1001 foreach ($show_user_results as $selected_user) {
1002 $active_id = (
int) $selected_user;
1005 $template =
new ilTemplate(
"tpl.il_as_tst_pass_details_overview_participants.html",
true,
true,
"Modules/Test");
1009 $pass_results = $this->results_factory->getPassResultsFor(
1016 $table = $this->results_presentation_factory->getPassResultsPresentationTable(
1021 $anchor =
'<a name="participant_active_' . $active_id .
'"></a>';
1023 $content[] = $anchor . $template->get() . $table->render();
1026 $toolbar->setParticipantSelectorOptions($anchors);
1028 $template =
new ilTemplate(
"tpl.il_as_tst_pass_details_overview_participants.html",
true,
true,
"Modules/Test");
1029 $template->setVariable(
'RESULTS_TOOLBAR',
$toolbar->getHTML());
1030 array_unshift($content, $template->get());
1032 $this->tpl->setVariable(
1034 implode(
'', $content)
1037 $this->
tabs->setBackTarget(
1038 $this->
lng->txt(
'back'),
1039 $this->
ctrl->getLinkTargetByClass([
'ilObjTestGUI',
'ilTestResultsGUI',
'ilParticipantsTestResultsGUI'])
1050 $active_id = (
int) $this->testrequest->raw(
"active_id");
1052 if (!$this->
getTestAccess()->checkResultsAccessForActiveId($active_id)) {
1053 ilObjTestGUI::accessViolationRedirect();
1056 $testSession = $this->testSessionFactory->getSession($active_id);
1059 if ($testSession->getTestId() != $this->
object->getTestId()) {
1060 ilObjTestGUI::accessViolationRedirect();
1063 if ($this->
object->getNrOfTries() == 1) {
1064 $this->
ctrl->setParameter($this,
"active_id", $active_id);
1066 $this->
ctrl->redirect($this,
"outParticipantsPassDetails");
1069 $ilTabs->setBackTarget(
1070 $this->
lng->txt(
'back'),
1071 $this->
ctrl->getLinkTargetByClass([
'ilObjTestGUI',
'ilTestResultsGUI',
'ilParticipantsTestResultsGUI'])
1074 $template =
new ilTemplate(
"tpl.il_as_tst_pass_overview_participants.html",
true,
true,
"Modules/Test");
1078 $template->setVariable(
'RESULTS_TOOLBAR', $this->
ctrl->getHTML(
$toolbar));
1082 $testResultHeaderLabelBuilder->setObjectiveOrientedContainerId($testSession->getObjectiveOrientedContainerId());
1083 $testResultHeaderLabelBuilder->setUserId($testSession->getUserId());
1084 $testResultHeaderLabelBuilder->setTestObjId($this->
object->getId());
1085 $testResultHeaderLabelBuilder->setTestRefId($this->
object->getRefId());
1086 $testResultHeaderLabelBuilder->initObjectiveOrientedMode();
1090 $testPassesSelector->setActiveId($testSession->getActiveId());
1091 $testPassesSelector->setLastFinishedPass($testSession->getLastFinishedPass());
1094 $passOverViewTableGUI->setActiveId($testSession->getActiveId());
1095 $passOverViewTableGUI->setResultPresentationEnabled(
true);
1096 $passOverViewTableGUI->setPassDetailsCommand(
'outParticipantsPassDetails');
1097 $passOverViewTableGUI->init();
1098 $passOverViewTableGUI->setData($this->
getPassOverviewTableData($testSession, $testPassesSelector->getExistingPasses(),
true));
1099 $passOverViewTableGUI->setTitle($testResultHeaderLabelBuilder->getPassOverviewHeaderLabel());
1100 $template->setVariable(
"PASS_OVERVIEW", $passOverViewTableGUI->getHTML());
1104 $gradingMessageBuilder->buildList();
1106 $template->setCurrentBlock(
'grading_message');
1107 $template->setVariable(
'GRADING_MESSAGE', $gradingMessageBuilder->getList());
1108 $template->parseCurrentBlock();
1112 $user_id = $this->
object->_getUserIdFromActiveId($active_id);
1115 if ($this->
object->getAnonymity()) {
1116 $template->setVariable(
"TEXT_HEADING", $this->
lng->txt(
"tst_result"));
1118 $uname = $this->
object->userLookupFullName($user_id,
true);
1119 $template->setVariable(
"TEXT_HEADING", sprintf($this->
lng->txt(
"tst_result_user_name"), $uname));
1120 $template->setVariable(
"USER_DATA", $user_data);
1124 $template->parseCurrentBlock();
1127 $this->tpl->setVariable(
"ADM_CONTENT", $template->get());
1132 $this->
tabs->clearSubTabs();
1133 $this->
tabs->setBackTarget($this->
lng->txt(
'tst_results_back_overview'), $this->
ctrl->getLinkTarget($this));
1135 $testSession = $this->testSessionFactory->getSession();
1137 if (!$this->
object->getShowPassDetails()) {
1138 $this->
ctrl->redirectByClass(
"ilobjtestgui",
"infoScreen");
1141 $active_id = $testSession->getActiveId();
1142 $user_id = $testSession->getUserId();
1144 $this->
ctrl->saveParameter($this,
"pass");
1145 $pass = $this->testrequest->int(
"pass");
1149 $objectivesList = null;
1151 $considerHiddenQuestions =
true;
1152 $considerOptionalQuestions =
true;
1155 $considerHiddenQuestions =
false;
1157 $testSequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($active_id, $pass);
1158 $testSequence->loadFromDb();
1159 $testSequence->loadQuestions();
1161 if ($this->
object->isRandomTest() && !$testSequence->isAnsweringOptionalQuestionsConfirmed()) {
1162 $considerOptionalQuestions =
false;
1168 $objectivesList->loadObjectivesTitles();
1170 $testResultHeaderLabelBuilder->setObjectiveOrientedContainerId($testSession->getObjectiveOrientedContainerId());
1171 $testResultHeaderLabelBuilder->setUserId($testSession->getUserId());
1172 $testResultHeaderLabelBuilder->setTestObjId($this->
object->getId());
1173 $testResultHeaderLabelBuilder->setTestRefId($this->
object->getRefId());
1174 $testResultHeaderLabelBuilder->initObjectiveOrientedMode();
1177 $tpl =
new ilTemplate(
'tpl.il_as_tst_pass_details_overview_participants.html',
true,
true,
"Modules/Test");
1182 if ($validator->isCertificateDownloadable($user_id, $this->object->getId())) {
1183 $toolbar->setCertificateLinkTarget($this->
ctrl->getLinkTarget($this,
'outCertificate'));
1194 if ($this->
object->isShowExamIdInTestResultsEnabled()) {
1195 if ($this->
object->isShowExamIdInTestResultsEnabled()) {
1197 $testSession->getActiveId(),
1207 $gradingMessageBuilder->buildMessage();
1208 $gradingMessageBuilder->sendMessage();
1211 $data = $this->
object->getCompleteEvaluationData();
1212 $reached =
$data->getParticipant($active_id)->getPass($pass)->getReachedPoints();
1213 $max =
$data->getParticipant($active_id)->getPass($pass)->getMaxPoints();
1214 $percent = $max ? $reached / $max * 100.0 : 0;
1215 $result =
$data->getParticipant($active_id)->getPass($pass)->getReachedPoints() .
" " . strtolower($this->
lng->txt(
"of")) .
" " .
$data->getParticipant($active_id)->getPass($pass)->getMaxPoints() .
" (" . sprintf(
"%2.2f", $percent) .
" %" .
")";
1217 $tpl->
setVariable(
"TOTAL_RESULT_TEXT", $this->
lng->txt(
'tst_stat_result_resultspoints'));
1221 $tpl->
setVariable(
"TEXT_RESULTS", $testResultHeaderLabelBuilder->getPassDetailsHeaderLabel($pass + 1));
1229 $pass_results = $this->results_factory->getPassResultsFor(
1236 $table = $this->results_presentation_factory->getPassResultsPresentationTable(
1245 $this->tpl->setContent(
1252 $testSession = $this->testSessionFactory->getSession();
1253 $active_id = $testSession->getActiveId();
1254 $user_id = $this->
user->getId();
1255 $uname = $this->
object->userLookupFullName($user_id,
true);
1257 if (!$this->
object->canShowTestResults($testSession)) {
1258 $this->
ctrl->redirectByClass(
"ilobjtestgui",
"infoScreen");
1261 $templatehead =
new ilTemplate(
"tpl.il_as_tst_results_participants.html",
true,
true,
"Modules/Test");
1262 $template =
new ilTemplate(
"tpl.il_as_tst_results_participant.html",
true,
true,
"Modules/Test");
1267 if ($validator->isCertificateDownloadable($user_id, $this->object->getId())) {
1268 $toolbar->setCertificateLinkTarget($this->
ctrl->getLinkTarget($this,
'outCertificate'));
1273 $templatehead->setVariable(
'RESULTS_TOOLBAR', $this->
ctrl->getHTML(
$toolbar));
1275 $passDetailsEnabled = $this->
object->getShowPassDetails();
1279 $testResultHeaderLabelBuilder->setObjectiveOrientedContainerId($testSession->getObjectiveOrientedContainerId());
1280 $testResultHeaderLabelBuilder->setUserId($testSession->getUserId());
1281 $testResultHeaderLabelBuilder->setTestObjId($this->
object->getId());
1282 $testResultHeaderLabelBuilder->setTestRefId($this->
object->getRefId());
1283 $testResultHeaderLabelBuilder->initObjectiveOrientedMode();
1286 $template->setCurrentBlock(
"pass_overview");
1289 $testPassesSelector->setActiveId($testSession->getActiveId());
1290 $testPassesSelector->setLastFinishedPass($testSession->getLastFinishedPass());
1293 $passOverViewTableGUI->setActiveId($testSession->getActiveId());
1294 $passOverViewTableGUI->setResultPresentationEnabled(
true);
1295 if ($passDetailsEnabled) {
1296 $passOverViewTableGUI->setPassDetailsCommand(
'outUserPassDetails');
1298 if ($this->
object->isPassDeletionAllowed()) {
1299 $passOverViewTableGUI->setPassDeletionCommand(
'confirmDeletePass');
1301 $passOverViewTableGUI->init();
1302 $passOverViewTableGUI->setData($this->
getPassOverviewTableData($testSession, $testPassesSelector->getReportablePasses(),
true));
1303 $passOverViewTableGUI->setTitle($testResultHeaderLabelBuilder->getPassOverviewHeaderLabel());
1304 $overview = $passOverViewTableGUI->getHTML();
1314 $lo_status->setUsrId($testSession->getUserId());
1315 $overview .=
"<br />" . $lo_status->getHTML();
1317 $template->setVariable(
"PASS_OVERVIEW", $overview);
1318 $template->parseCurrentBlock();
1322 $gradingMessageBuilder->buildMessage();
1323 $gradingMessageBuilder->sendMessage();
1329 if ($this->
object->getAnonymity()) {
1330 $template->setVariable(
"TEXT_HEADING", $this->
lng->txt(
"tst_result"));
1332 $template->setVariable(
"TEXT_HEADING", sprintf($this->
lng->txt(
"tst_result_user_name"), $uname));
1333 $template->setVariable(
"USER_DATA", $user_data);
1338 $templatehead->setVariable(
"RESULTS_PARTICIPANT", $template->get());
1339 $this->tpl->setContent($templatehead->get());
1344 if (!$this->
object->getShowSolutionPrintview()) {
1345 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
"no_permission"),
true);
1346 $this->
ctrl->redirectByClass(
"ilobjtestgui",
"infoScreen");
1349 $template =
new ilTemplate(
"tpl.il_as_tst_info_list_of_answers.html",
true,
true,
"Modules/Test");
1352 if ($this->testrequest->isset(
'pass')) {
1353 $pass = $this->testrequest->int(
'pass');
1355 $user_id = $this->
user->getId();
1357 $testSession = $this->testSessionFactory->getSession();
1358 $active_id = $testSession->getActiveId();
1360 $template->setVariable(
"TEXT_RESULTS", $this->
lng->txt(
"tst_passes"));
1363 $testPassesSelector->setActiveId($testSession->getActiveId());
1364 $testPassesSelector->setLastFinishedPass($testSession->getLastFinishedPass());
1367 $passOverViewTableGUI->setActiveId($testSession->getActiveId());
1368 $passOverViewTableGUI->setResultPresentationEnabled(
false);
1369 $passOverViewTableGUI->setPassDetailsCommand(
'outUserListOfAnswerPasses');
1370 $passOverViewTableGUI->init();
1371 $passOverViewTableGUI->setData($this->
getPassOverviewTableData($testSession, $testPassesSelector->getClosedPasses(),
false));
1372 $template->setVariable(
"PASS_OVERVIEW", $passOverViewTableGUI->getHTML());
1375 if ($pass !== null) {
1378 $objectivesList = null;
1381 $testSequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($active_id, $pass);
1382 $testSequence->loadFromDb();
1383 $testSequence->loadQuestions();
1388 $objectivesList->loadObjectivesTitles();
1390 $testResultHeaderLabelBuilder->setObjectiveOrientedContainerId($testSession->getObjectiveOrientedContainerId());
1391 $testResultHeaderLabelBuilder->setUserId($testSession->getUserId());
1392 $testResultHeaderLabelBuilder->setTestObjId($this->
object->getId());
1393 $testResultHeaderLabelBuilder->setTestRefId($this->
object->getRefId());
1394 $testResultHeaderLabelBuilder->initObjectiveOrientedMode();
1397 $result_array = $this->
object->getTestResult(
1405 $user_id = $this->
object->_getUserIdFromActiveId($active_id);
1406 $showAllAnswers =
true;
1407 if ($this->
object->isExecutable($testSession, $user_id)) {
1408 $showAllAnswers =
false;
1411 $answers = $this->
getPassListOfAnswers($result_array, $active_id, $pass,
false, $showAllAnswers,
false,
false,
false, $objectivesList, $testResultHeaderLabelBuilder);
1412 $template->setVariable(
"PASS_DETAILS", $answers);
1414 $template->setVariable(
"FORMACTION", $this->
ctrl->getFormAction($this));
1415 $template->setVariable(
"PRINT_TEXT", $this->
lng->txt(
"print"));
1416 $template->setVariable(
"PRINT_URL",
"javascript:window.print();");
1419 $template->setVariable(
"USER_DATA", $user_data);
1420 $template->setVariable(
"TEXT_LIST_OF_ANSWERS", $this->
lng->txt(
"tst_list_of_answers"));
1421 if (strlen($signature)) {
1422 $template->setVariable(
"SIGNATURE", $signature);
1424 if (!is_null($pass) && $this->
object->isShowExamIdInTestResultsEnabled()) {
1425 $template->setCurrentBlock(
'exam_id_footer');
1427 $testSession->getActiveId(),
1430 $template->setVariable(
'EXAM_ID_TXT', $this->
lng->txt(
'exam_id'));
1431 $template->parseCurrentBlock();
1435 $this->tpl->setVariable(
"ADM_CONTENT", $template->get());
1442 if ($this->testrequest->isset(
"pass") && (strlen($this->testrequest->raw(
"pass")) > 0)) {
1443 $this->
ctrl->saveParameter($this,
"pass");
1444 $this->
ctrl->saveParameter($this,
"active_id");
1445 $this->outTestResults(
false, $this->testrequest->raw(
"pass"));
1447 $this->outTestResults(
false);
1458 ilObjTestGUI::accessViolationRedirect();
1461 $this->
object->setAccessFilteredParticipantList(
1462 $this->
object->buildStatisticsAccessFilteredParticipantList()
1467 $data = $this->
object->getCompleteEvaluationData();
1468 $color_class = array(
"tblrow1",
"tblrow2");
1470 $this->tpl->addBlockFile(
"ADM_CONTENT",
"adm_content",
"tpl.il_as_tst_eval_single_answers.html",
"Modules/Test");
1471 $found_participants =
$data->getParticipants();
1472 if ($found_participants === []) {
1473 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
"tst_no_evaluation_data"));
1478 foreach (
$data->getQuestionTitles() as $question_id => $question_title) {
1482 foreach ($found_participants as $userdata) {
1483 $pass = $userdata->getScoredPass();
1484 if (is_object($userdata->getPass($pass))) {
1485 $question = $userdata->getPass($pass)->getAnsweredQuestionByQuestionId($question_id);
1486 if (is_array($question)) {
1492 $this->
ctrl->setParameter($this,
"qid", $question_id);
1496 && $question_object->
hasFileUploads($this->object->getTestId())) {
1497 $download =
'<a href="' . $this->
ctrl->getLinkTarget($this,
"exportFileUploadsForAllParticipants") .
'">' 1498 . $this->
lng->txt(
'download') .
'</a>';
1501 'qid' => $question_id,
1502 'question_title' => htmlspecialchars($question_title),
1503 'number_of_answers' => $answered,
1504 'output' =>
"<a target='_blank' href=\"" . $this->
ctrl->getLinkTarget($this,
"exportQuestionForAllParticipants") .
"\">" . $this->
lng->txt(
"print") .
"</a>",
1505 'file_uploads' => $download
1510 $table_gui->setTitle($this->
lng->txt(
'tst_answered_questions_test'));
1511 $table_gui->setData($rows);
1513 $this->tpl->setVariable(
'TBL_SINGLE_ANSWERS', $table_gui->getHTML());
1519 $pdfGenerator =
new ilPdfGenerator($ilUserCertificateRepository);
1524 $this->
lng->txt(
'error_creating_certificate_pdf')
1527 $pdfAction->
downloadPdf($this->
user->getId(), $this->
object->getId());
1532 if ($this->testrequest->isset(
'context') && strlen($this->testrequest->raw(
'context'))) {
1533 $context = $this->testrequest->raw(
'context');
1538 if (!$this->
object->isPassDeletionAllowed()) {
1543 $confirm->build((
int) $this->testrequest->raw(
"active_id"), (
int) $this->testrequest->raw(
"pass"),
$context);
1545 $this->tpl->setContent($this->
ctrl->getHTML($confirm));
1558 $this->
ctrl->redirect($this,
'outUserResultsOverview');
1563 $this->
ctrl->redirectByClass(
'ilObjTestGUI',
'infoScreen');
1569 if (isset($_POST[
'context']) && strlen($_POST[
'context'])) {
1575 if (!$this->
object->isPassDeletionAllowed()) {
1584 if (isset($_POST[
'active_id']) && (
int) $_POST[
'active_id']) {
1585 $active_fi = $_POST[
'active_id'];
1588 if (isset($_POST[
'pass']) && is_numeric($_POST[
'pass'])) {
1589 $pass = $_POST[
'pass'];
1592 if (is_null($active_fi) || is_null($pass)) {
1593 $this->
ctrl->redirect($this,
'outUserResultsOverview');
1596 if ($pass == $this->
object->_getResultPass($active_fi)) {
1597 $this->
ctrl->redirect($this,
'outUserResultsOverview');
1601 $result =
$ilDB->query(
" 1602 SELECT tst_active.tries, tst_active.last_finished_pass, tst_sequence.pass 1604 LEFT JOIN tst_sequence 1605 ON tst_sequence.active_fi = tst_active.active_id 1606 AND tst_sequence.pass = tst_active.tries 1607 WHERE tst_active.active_id = {$ilDB->quote($active_fi, 'integer')} 1610 $row =
$ilDB->fetchAssoc($result);
1612 $tries = $row[
'tries'];
1613 $lastFinishedPass = is_numeric($row[
'last_finished_pass']) ? $row[
'last_finished_pass'] : -1;
1615 if ($pass < $lastFinishedPass) {
1616 $isActivePass =
false;
1617 $must_renumber =
true;
1618 } elseif ($pass == $lastFinishedPass) {
1619 $isActivePass =
false;
1621 if ($tries == $row[
'pass']) {
1622 $must_renumber =
true;
1624 $must_renumber =
false;
1626 } elseif ($pass == $row[
'pass']) {
1627 $isActivePass =
true;
1628 $must_renumber =
false;
1630 throw new ilTestException(
'This should not happen, please contact Bjoern Heyser to clean up this pass salad!');
1633 if ($isActivePass) {
1634 $this->
ctrl->redirect($this,
'outUserResultsOverview');
1638 ($lastFinishedPass == 0 && $tries == 1 && $tries != $row[
'pass'])
1639 || ($isActivePass ==
true)
1652 WHERE active_id = ' .
$ilDB->quote($active_fi,
'integer')
1654 } elseif (!$isActivePass) {
1657 SET tries = ' .
$ilDB->quote($tries - 1,
'integer') .
', 1658 last_finished_pass = ' .
$ilDB->quote($lastFinishedPass - 1,
'integer') .
' 1659 WHERE active_id = ' .
$ilDB->quote($active_fi,
'integer')
1666 WHERE active_fi = ' .
$ilDB->quote($active_fi,
'integer') .
' 1667 AND pass = ' .
$ilDB->quote($pass,
'integer')
1670 if ($must_renumber) {
1672 'UPDATE tst_manual_fb 1674 WHERE active_fi = ' .
$ilDB->quote($active_fi,
'integer') .
' 1675 AND pass > ' .
$ilDB->quote($pass,
'integer')
1684 FROM tst_pass_result 1685 WHERE active_fi = ' .
$ilDB->quote($active_fi,
'integer') .
' 1686 AND pass = ' .
$ilDB->quote($pass,
'integer')
1689 if ($must_renumber) {
1691 'UPDATE tst_pass_result 1693 WHERE active_fi = ' .
$ilDB->quote($active_fi,
'integer') .
' 1694 AND pass > ' .
$ilDB->quote($pass,
'integer')
1701 WHERE active_fi = ' .
$ilDB->quote($active_fi,
'integer') .
' 1702 AND pass = ' .
$ilDB->quote($pass,
'integer')
1705 if ($must_renumber) {
1707 'UPDATE tst_sequence 1709 WHERE active_fi = ' .
$ilDB->quote($active_fi,
'integer') .
' 1710 AND pass > ' .
$ilDB->quote($pass,
'integer')
1718 WHERE active_fi = ' .
$ilDB->quote($active_fi,
'integer') .
' 1719 AND pass = ' .
$ilDB->quote($pass,
'integer')
1722 if ($must_renumber) {
1724 'UPDATE tst_solutions 1726 WHERE active_fi = ' .
$ilDB->quote($active_fi,
'integer') .
' 1727 AND pass > ' .
$ilDB->quote($pass,
'integer')
1734 FROM tst_test_result 1735 WHERE active_fi = ' .
$ilDB->quote($active_fi,
'integer') .
' 1736 AND pass = ' .
$ilDB->quote($pass,
'integer')
1739 if ($must_renumber) {
1741 'UPDATE tst_test_result 1743 WHERE active_fi = ' .
$ilDB->quote($active_fi,
'integer') .
' 1744 AND pass > ' .
$ilDB->quote($pass,
'integer')
1751 FROM qpl_hint_tracking 1752 WHERE qhtr_active_fi = ' .
$ilDB->quote($active_fi,
'integer') .
' 1753 AND qhtr_pass = ' .
$ilDB->quote($pass,
'integer')
1756 if ($must_renumber) {
1758 'UPDATE qpl_hint_tracking 1759 SET qhtr_pass = qhtr_pass - 1 1760 WHERE qhtr_active_fi = ' .
$ilDB->quote($active_fi,
'integer') .
' 1761 AND qhtr_pass > ' .
$ilDB->quote($pass,
'integer')
1771 WHERE active_fi = ' .
$ilDB->quote($active_fi,
'integer') .
' 1772 AND pass = ' .
$ilDB->quote($pass,
'integer')
1775 if ($must_renumber) {
1779 WHERE active_fi = ' .
$ilDB->quote($active_fi,
'integer') .
' 1780 AND pass > ' .
$ilDB->quote($pass,
'integer')
1788 $this->
object->updateTestResultCache((
int) $active_fi);
1793 protected function getFilteredTestResult(
int $active_id,
int $pass,
bool $considerHiddenQuestions,
bool $considerOptionalQuestions): array
1798 $resultData = $this->
object->getTestResult($active_id, $pass,
false, $considerHiddenQuestions);
1800 foreach ($resultData as $resultItemKey => $resultItemValue) {
1801 if ($resultItemKey ===
'test' || $resultItemKey ===
'pass') {
1805 $questionIds[] = $resultItemValue[
'qid'];
1811 $questionList->setParentObjId($this->
object->getId());
1812 $questionList->setParentObjectType($this->
object->getType());
1813 $questionList->setIncludeQuestionIdsFilter($questionIds);
1815 foreach ($table_gui->getFilterItems() as $item) {
1816 if (substr($item->getPostVar(), 0, strlen(
'tax_')) ==
'tax_') {
1817 $v = $item->getValue();
1819 if (is_array($v) && count($v) && !(
int) $v[0]) {
1823 $taxId = substr($item->getPostVar(), strlen(
'tax_'));
1824 $questionList->addTaxonomyFilter($taxId, $item->getValue(), $this->
object->getId(),
'tst');
1825 } elseif ($item->getValue() !==
false) {
1826 $questionList->addFieldFilter($item->getPostVar(), $item->getValue());
1830 $questionList->load();
1832 $filteredTestResult = [];
1834 foreach ($resultData as $resultItemKey => $resultItemValue) {
1835 if ($resultItemKey ===
'test' || $resultItemKey ===
'pass') {
1839 if (!$questionList->isInList($resultItemValue[
'qid'])) {
1843 $filteredTestResult[] = $resultItemValue;
1846 return $filteredTestResult;
1851 $active_id = (
int) $this->testrequest->raw(
"active_id");
1852 $access_filter = $this->participant_access_filter->getManageParticipantsUserFilter($this->ref_id);
1855 $participant_data->setActiveIdsFilter([$active_id]);
1856 $participant_data->setParticipantAccessFilter($access_filter);
1857 $participant_data->load($this->
object->getTestId());
1859 if (!in_array($active_id, $participant_data->getActiveIds())) {
1864 $test_session->loadFromDb($active_id);
1866 if ($test_session->getLastStartedPass() === $test_session->getLastFinishedPass()) {
1867 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'tst_already_submitted'),
true);
1871 if (($this->
object->isEndingTimeEnabled() || $this->
object->getEnableProcessingTime())
1872 && !$this->
object->endingTimeReached()
1873 && !$this->
object->isMaxProcessingTimeReached(
1874 $this->
object->getStartingTimeOfUser($active_id),
1877 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'finish_pass_for_user_in_processing_time'));
1882 $cgui->setHeaderText(sprintf(
1883 $this->
lng->txt(
"finish_pass_for_user_confirmation"),
1884 $participant_data->getFormatedFullnameByActiveId($active_id)
1887 $this->
ctrl->setParameter($this,
'active_id', $active_id);
1888 $cgui->setFormAction($this->
ctrl->getFormAction($this,
"participants"));
1890 $cgui->setCancel($this->
lng->txt(
"cancel"),
"redirectBackToParticipantsScreen");
1891 $cgui->setConfirm($this->
lng->txt(
"proceed"),
"confirmFinishTestPassForUser");
1893 $this->tpl->setContent($cgui->getHTML());
1898 $active_id = (
int) $this->testrequest->raw(
"active_id");
1899 $access_filter = $this->participant_access_filter->getManageParticipantsUserFilter($this->ref_id);
1902 $participant_data->setActiveIdsFilter(array($active_id));
1903 $participant_data->setParticipantAccessFilter($access_filter);
1904 $participant_data->load($this->
object->getTestId());
1906 if (!in_array($active_id, $participant_data->getActiveIds())) {
1911 $test_session->loadFromDb($active_id);
1913 if ($test_session->getLastStartedPass() === $test_session->getLastFinishedPass()) {
1914 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'tst_already_submitted'),
true);
1918 $this->
object->updateTestPassResults(
1920 $test_session->getPass(),
1921 $this->
object->areObligationsEnabled(),
1923 $this->
object->getId()
1934 $this->tpl->setOnScreenMessage(
1936 $this->
lng->txt(
'finish_pass_for_all_users_in_processing_time'),
1943 $cgui->setFormAction($this->
ctrl->getFormAction($this));
1944 $cgui->setHeaderText($this->
lng->txt(
"finish_pass_for_all_users"));
1945 $cgui->setCancel($this->
lng->txt(
"cancel"),
"redirectBackToParticipantsScreen");
1946 $cgui->setConfirm($this->
lng->txt(
"proceed"),
"confirmFinishTestPassForAllUser");
1947 $this->tpl->setContent($cgui->getHTML());
1952 if (!$this->
object->isEndingTimeEnabled() && !$this->
object->getEnableProcessingTime()
1953 || $this->
object->endingTimeReached()) {
1957 $access_filter = $this->participant_access_filter->getManageParticipantsUserFilter($this->ref_id);
1959 $participant_list->initializeFromDbRows($this->
object->getTestParticipants());
1961 foreach ($participant_list->getAccessFilteredList($access_filter) as $participant) {
1962 if ($participant->hasUnfinishedPasses()
1963 && !$this->
object->isMaxProcessingTimeReached(
1964 $this->
object->getStartingTimeOfUser($participant->getActiveId()),
1965 $participant->getActiveId()
1976 $access_filter = $this->participant_access_filter->getManageParticipantsUserFilter($this->ref_id);
1979 $participant_list->initializeFromDbRows($this->
object->getTestParticipants());
1980 $filtered_participant_list = $participant_list->getAccessFilteredList($access_filter);
1982 foreach ($filtered_participant_list as $participant) {
1983 if (!$participant->hasUnfinishedPasses()) {
1988 $test_session->loadFromDb($participant->getActiveId());
1990 $this->
object->updateTestPassResults(
1991 $participant->getActiveId(),
1992 $test_session->getPass(),
1993 $this->
object->areObligationsEnabled(),
1995 $this->
object->getId()
2007 $process_locker = $this->processLockerFactory->withContextId($active_id)->getLocker();
2010 $this->testSessionFactory->getSession($active_id),
2018 $this->
ctrl->redirectByClass(
"ilTestParticipantsGUI");
2023 return $this->object;
2029 "tpl.question_statistics_print_view.html",
2042 foreach ($this->global_screen->layout()->meta()->getJs()->getItemsInOrderOfDelivery() as $js) {
2043 $path = explode(
"?", $js->getContent());
2047 foreach ($this->global_screen->layout()->meta()->getOnLoadCode()->getItemsInOrderOfDelivery() as $code) {
2060 $this->
http->saveResponse($this->
http->response()->withBody(
2061 Streams::ofString($page)
2063 $this->
http->sendResponse();
2064 $this->
http->close();
2069 if ($this->
object->getAnonymity()) {
2071 $this->
lng->txt(
"tst_eval_results_by_pass_lo"),
2076 $this->
lng->txt(
"tst_result_user_name_pass"),
static get(string $a_var)
populateExamId(ilTemplate $tpl, int $active_id, int $pass)
ilTestProcessLockerFactory $processLockerFactory
static getContentPrintStyle()
ilComponentRepository $component_repository
getQuestionResultForTestUsers(int $question_id, int $test_id)
Class ilTestPassFinishTasks.
singleResults()
Creates user results for single questions.
getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, $overwrite_anonymity=false)
Returns the user data for a test results output.
hasFileUploads(int $test_id)
confirmFinishTestPassForAllUser()
special template class to simplify handling of ITX/PEAR
const QUESTION_SET_TYPE_RANDOM
outParticipantsResultsOverview()
setTestAccess($testAccess)
static _lookupFullname(int $a_user_id)
Class ChatMainBarProvider .
static lookupPassResultsUpdateTimestamp($active_id, $pass)
getObjectiveOrientedContainer()
exportAggregatedResults($cmd='')
ilGlobalTemplateInterface ilTemplate $tpl
sk 2023-08-01: We need this union type, even if it is wrong! To change this
TableGUI class for results by question.
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
get(string $part=self::DEFAULT_BLOCK)
Renders the given block and returns the html string.
setContextResultPresentation(bool $contextResultPresentation)
exportEvaluation($cmd="")
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
printToString()
Use this method to get the finally rendered page as string.
getResultsSignature()
Returns HTML code for a signature field.
TableGUI class for evaluation of all users.
setVariable(string $variable, $value='')
Sets the given variable to the given value.
static getStyleSheetLocation(string $mode="output", string $a_css_name="", string $a_css_location="")
get full style sheet file name (path inclusive) of current user
confirmFinishTestPassForUser()
__construct(ilObjTest $object)
ilTestEvaluationGUI constructor
buildPassOverviewTableGUI(ilTestEvaluationGUI $target_gui)
Base Exception for all Exceptions relating to Modules/Test.
isGradingMessageRequired()
buildUserTestResultsToolbarGUI()
static getASCIIFilename(string $a_filename)
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.
static _getUserIdFromActiveId(int $active_id)
getEvaluationQuestionId($question_id, $original_id="")
Returns the ID of a question for evaluation purposes.
static instantiateQuestion(int $question_id)
static getInstance(ilTestSession $a_test_session)
setParticipantAccessFilter(Closure $participantAccessFilter)
static _enabledAssessmentLogging()
static http()
Fetches the global http state from ILIAS.
const CONTEXT_PASS_OVERVIEW
outParticipantsPassDetails()
Output of the pass details of an existing test pass for the test statistics.
getFilteredTestResult(int $active_id, int $pass, bool $considerHiddenQuestions, bool $considerOptionalQuestions)
setActiveIdsFilter(array $active_ids_filter)
getGradingMessageBuilder(int $active_id)
multiParticipantsPassDetails()
static _getResultPass($active_id)
Retrieves the pass number that should be counted for a given user.
prepareContentForPrint(string $question_title, string $question_content)
Validates if an active certificate is stored in the database and can be downloaded by the user...
finishTestPassForSingleUser()
Output class for assessment test evaluation.
buildPassDetailsOverviewTableGUI(ilTestServiceGUI|ilParticipantsTestResultsGUI $target_gui, string $target_cmd)
redirectBackToParticipantsScreen()
addJavaScript(string $a_js_file, bool $a_add_version_parameter=true, int $a_batch=2)
Add a javascript file that should be included in the header.
static getSyntaxStylePath()
static _lookupFields(int $a_user_id)
lookup fields (deprecated; use more specific methods instead)
ilObjectDataCache $obj_cache
addOnLoadCode(string $a_code, int $a_batch=2)
Add on load code.
static getContentStylePath(int $a_style_id, bool $add_random=true, bool $add_token=true)
get content style path static (to avoid full reading)
buildResultsTitle(int $active_id, int $pass)
const CONTEXT_INFO_SCREEN
setTitle(string $a_title, string $a_icon="", string $a_icon_alt="")
exportFileUploadsForAllParticipants()
Creates a ZIP file containing all file uploads for a given question in a test.
setCurrentBlock(string $part=self::DEFAULT_BLOCK)
Sets the template to the given block.
Just a wrapper class to create Unit Test for other classes.
createPDF(int $userId, int $objectId)
performFinishTasks(ilTestProcessLocker $process_locker)
redirectToPassDeletionContext($context)
ilTestParticipantData $participantData
hasUsersWithWorkingTimeAvailable()
buildQuestionRelatedObjectivesList(ilLOTestQuestionAdapter $objectives_adapter, ilTestQuestionSequence $test_sequence)
static getInstance()
Singleton: get instance for use in ILIAS requests with a config loaded from the settings.
exportQuestionForAllParticipants()
Creates a PDF representation of the answers for a given question in a test.
finishTestPass(int $active_id)
Service GUI class for tests.
exportCertificateArchive()
parseCurrentBlock(string $block_name=self::DEFAULT_BLOCK)
Parses the given block.
outUserListOfAnswerPasses()
populatePassFinishDate(ilTemplate $tpl, ?int $pass_finish_date)
static clear(string $a_var)
static set(string $a_var, $a_val)
Set a value.
eval_a()
Output of anonymous aggregated results for the test.
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...
addCss(string $a_css_file, string $media="screen")
Add a css file that should be included in the header.
static lookupExamId($active_id, $pass)
downloadPdf(int $userId, int $objectId)
static _lookupLogin(int $a_user_id)