19require_once
'Modules/Test/classes/inc.AssessmentConstants.php';
275 public function __construct($a_id = 0,
bool $a_call_by_reference =
true)
278 $this->db =
$DIC[
'ilDB'];
283 $this->testrequest =
$DIC->test()->internal()->request();
287 $this->mark_schema->createSimpleSchema(
298 $this->score_settings =
null;
300 $this->author =
$ilUser->fullname;
301 $this->introductionEnabled =
false;
302 $this->introduction =
"";
303 $this->questions = array();
305 $this->instant_verification = 0;
306 $this->answer_feedback_points = 0;
307 $this->reporting_date =
"";
308 $this->nr_of_tries = 0;
310 $this->use_previous_answers = 1;
311 $this->title_output = 0;
312 $this->starting_time =
"";
313 $this->ending_time =
"";
314 $this->processing_time =
"";
315 $this->enable_processing_time =
"0";
316 $this->reset_processing_time = 0;
317 $this->ects_output =
false;
318 $this->ects_fx =
null;
319 $this->shuffle_questions =
false;
320 $this->mailnottype = 0;
321 $this->show_summary = 8;
322 $this->answer_feedback = 0;
323 $this->password =
"";
324 $this->allowedUsers =
"";
325 $this->_showfinalstatement =
false;
326 $this->_finalstatement =
"";
327 $this->_showinfo =
true;
328 $this->_forcejs =
true;
329 $this->_customStyle =
"";
330 $this->allowedUsersTimeGap =
"";
331 $this->anonymity = 0;
332 $this->show_cancel = 0;
333 $this->show_marker = 0;
334 $this->fixed_participants = 0;
335 $this->testSession =
false;
336 $this->testSequence =
false;
337 $this->mailnotification = 0;
339 $this->ects_grades = array(
347 $this->autosave =
false;
348 $this->autosave_ival = 30000;
350 $this->enable_examview =
false;
351 $this->show_examview_html =
false;
352 $this->show_examview_pdf =
false;
353 $this->enable_archiving =
false;
355 $this->template_id =
'';
356 $this->redirection_mode = 0;
357 $this->redirection_url =
null;
358 $this->show_exam_id_in_test_pass_enabled =
false;
359 $this->sign_submission =
false;
360 $this->char_selector_availability = 0;
361 $this->char_selector_definition =
null;
363 $this->showGradingStatusEnabled =
true;
364 $this->showGradingMarkEnabled =
true;
366 $this->followupQuestionAnswerFixationEnabled =
false;
367 $this->instantFeedbackAnswerFixationEnabled =
false;
369 $this->testFinalBroken =
false;
371 $this->tmpCopyWizardCopyId =
null;
397 $id = parent::create();
404 if (!parent::update()) {
419 public function delete():
bool
422 if (!parent::delete()) {
433 $qsaImportFails->deleteRegisteredImportFails();
435 $sltImportFails->deleteRegisteredImportFails();
445 $component_repository =
$DIC[
'component.repository'];
449 $participantData->load($this->
getTestId());
453 "DELETE FROM tst_mark WHERE test_fi = %s",
459 "DELETE FROM tst_tests WHERE test_id = %s",
465 $testQuestionSetConfigFactory->getQuestionSetConfig()->removeQuestionSetRelatedData();
468 $directory = $tst_data_dir .
"/tst_" . $this->
getId();
469 if (is_dir($directory)) {
477 foreach (
$mobs as $mob) {
495 if (!is_writable($tst_data_dir)) {
496 $this->
ilias->raiseError(
"Test Data Directory (" . $tst_data_dir
497 .
") not writeable.", $this->
ilias->error_obj->MESSAGE);
501 $tst_dir = $tst_data_dir .
"/tst_" . $this->
getId();
503 if (!@is_dir($tst_dir)) {
504 $this->
ilias->raiseError(
"Creation of Test Directory failed.", $this->
ilias->error_obj->MESSAGE);
507 $export_dir = $tst_dir .
"/export";
509 if (!@is_dir($export_dir)) {
510 $this->
ilias->raiseError(
"Creation of Export Directory failed.", $this->
ilias->error_obj->MESSAGE);
525 public function getExportFiles(
string $dir =
''): array
528 if (!@is_dir($dir) || !is_writable($dir)) {
533 foreach (
new DirectoryIterator($dir) as $file) {
537 if ($file->isDir()) {
541 $files[] = $file->getBasename();
551 if (strlen($a_import_dir)) {
589 if (!is_writable($tst_data_dir)) {
591 .
") not writeable.",
$ilias->error_obj->FATAL);
595 $tst_dir = $tst_data_dir .
"/tst_import";
597 if (!@is_dir($tst_dir)) {
612 $result =
$ilDB->queryF(
613 "SELECT DISTINCT(qpl_qst_type.type_tag) foundtypes FROM qpl_questions, tst_test_result, qpl_qst_type, tst_active WHERE tst_test_result.question_fi = qpl_questions.question_id AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id AND tst_test_result.active_fi = tst_active.active_id AND tst_active.test_fi = %s",
618 while ($row =
$ilDB->fetchAssoc($result)) {
619 if (strcmp($row[
'foundtypes'],
'assSingleChoice') == 0) {
631 $result =
$ilDB->queryF(
632 "SELECT DISTINCT(qpl_qst_type.type_tag) foundtypes FROM qpl_questions, tst_test_result, qpl_qst_type, tst_active WHERE tst_test_result.question_fi = qpl_questions.question_id AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id AND tst_test_result.active_fi = tst_active.active_id AND tst_active.test_fi = %s",
636 if ($result->numRows() == 1) {
637 $row =
$ilDB->fetchAssoc($result);
638 if (strcmp($row[
'foundtypes'],
'assSingleChoice') == 0) {
656 $result =
$ilDB->queryF(
658 SELECT DISTINCT(qpl_qst_sc.shuffle) foundshuffles
664 WHERE tst_test_result.question_fi = qpl_questions.question_id
665 AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id
666 AND tst_test_result.active_fi = tst_active.active_id
667 AND qpl_questions.question_id = qpl_qst_sc.question_fi
668 AND tst_active.test_fi = %s
669 AND qpl_qst_type.type_tag = %s
671 array(
'integer',
'text'),
672 array($this->
getTestId(),
'assSingleChoice')
674 if ($result->numRows() == 1) {
675 $row =
$ilDB->fetchAssoc($result);
676 return ($row[
'foundshuffles'] == 0);
683 if (!count($this->mark_schema->mark_steps)) {
699 $component_repository =
$DIC[
'component.repository'];
706 return $test->isComplete($testQuestionSetConfigFactory->getQuestionSetConfig());
721 SET ects_output = %s, ects_a = %s, ects_b = %s, ects_c = %s, ects_d = %s, ects_e = %s, ects_fx = %s
723 array(
'text',
'float',
'float',
'float',
'float',
'float',
'float',
'integer'),
726 $grades[
'A'], $grades[
'B'], $grades[
'C'], $grades[
'D'], $grades[
'E'],
740 if ($this->
isComplete($testQuestionSetConfig)) {
745 "UPDATE tst_tests SET complete = %s WHERE test_id = %s",
746 array(
'text',
'integer'),
747 array($complete, $this->test_id)
769 $completecontent =
"";
771 $completecontent .= $content;
780 public function saveToDb(
bool $properties_only =
false): void
785 $component_repository =
$DIC[
'component.repository'];
793 $testQuestionSetConfig = $testQuestionSetConfigFactory->getQuestionSetConfig();
795 if ($this->test_id == -1) {
797 $next_id =
$ilDB->nextId(
'tst_tests');
799 $ilDB->insert(
'tst_tests', array(
800 'test_id' => array(
'integer', $next_id),
801 'obj_fi' => array(
'integer', $this->
getId()),
802 'author' => array(
'text', $this->
getAuthor()),
806 'showinfo' => array(
'integer', $this->
getShowInfo()),
807 'forcejs' => array(
'integer', $this->
getForceJS()),
819 'nr_of_tries' => array(
'integer', $this->
getNrOfTries()),
821 'kiosk' => array(
'integer', $this->
getKiosk()),
831 'complete' => array(
'text', $this->
isComplete($testQuestionSetConfig)),
833 'ects_a' => array(
'float', strlen($this->ects_grades[
"A"]) ? $this->ects_grades[
"A"] : 90),
834 'ects_b' => array(
'float', strlen($this->ects_grades[
"B"]) ? $this->ects_grades[
"B"] : 65),
835 'ects_c' => array(
'float', strlen($this->ects_grades[
"C"]) ? $this->ects_grades[
"C"] : 35),
836 'ects_d' => array(
'float', strlen($this->ects_grades[
"D"]) ? $this->ects_grades[
"D"] : 10),
837 'ects_e' => array(
'float', strlen($this->ects_grades[
"E"]) ? $this->ects_grades[
"E"] : 0),
838 'ects_fx' => array(
'float', $this->
getECTSFX()),
848 'created' => array(
'integer', time()),
849 'tstamp' => array(
'integer', time()),
851 'template_id' => array(
'integer', $this->
getTemplate()),
855 'autosave' => array(
'integer', (
int) $this->
getAutosave()),
877 $this->test_id = $next_id;
886 $result =
$ilDB->queryF(
887 "SELECT * FROM tst_tests WHERE test_id = %s",
889 array($this->test_id)
891 if ($result->numRows() == 1) {
892 $oldrow =
$ilDB->fetchAssoc($result);
899 'author' => array(
'text', $this->
getAuthor()),
903 'showinfo' => array(
'integer', $this->
getShowInfo()),
904 'forcejs' => array(
'integer', $this->
getForceJS()),
916 'nr_of_tries' => array(
'integer', $this->
getNrOfTries()),
918 'kiosk' => array(
'integer', $this->
getKiosk()),
928 'complete' => array(
'text', $this->
isComplete($testQuestionSetConfig)),
930 'ects_a' => array(
'float', strlen($this->ects_grades[
"A"]) ? $this->ects_grades[
"A"] :
null),
931 'ects_b' => array(
'float', strlen($this->ects_grades[
"B"]) ? $this->ects_grades[
"B"] :
null),
932 'ects_c' => array(
'float', strlen($this->ects_grades[
"C"]) ? $this->ects_grades[
"C"] :
null),
933 'ects_d' => array(
'float', strlen($this->ects_grades[
"D"]) ? $this->ects_grades[
"D"] :
null),
934 'ects_e' => array(
'float', strlen($this->ects_grades[
"E"]) ? $this->ects_grades[
"E"] :
null),
935 'ects_fx' => array(
'float', $this->
getECTSFX()),
946 'tstamp' => array(
'integer', time()),
948 'template_id' => array(
'integer', $this->
getTemplate()),
952 'autosave' => array(
'integer', (
int) $this->
getAutosave()),
976 'test_id' => array(
'integer', $this->
getTestId())
981 $logresult =
$ilDB->queryF(
982 "SELECT * FROM tst_tests WHERE test_id = %s",
987 if ($logresult->numRows() == 1) {
988 $newrow =
$ilDB->fetchAssoc($logresult);
990 $changed_fields = array();
991 foreach ($oldrow as
$key => $value) {
992 if (strcmp($oldrow[
$key], $newrow[
$key]) != 0) {
993 array_push($changed_fields,
"$key: " . $oldrow[
$key] .
" => " . $newrow[
$key]);
996 $changes = join(
", ", $changed_fields);
997 if (count($changed_fields) > 0) {
1005 $aresult =
$ilDB->queryF(
1006 "SELECT active_id FROM tst_active WHERE test_fi = %s AND tries >= %s AND submitted = %s",
1007 array(
'integer',
'integer',
'integer'),
1010 while ($row =
$ilDB->fetchAssoc($aresult)) {
1012 "UPDATE tst_active SET submitted = %s, submittimestamp = %s WHERE active_id = %s",
1013 array(
'integer',
'timestamp',
'integer'),
1014 array(1, date(
'Y-m-d H:i:s'), $row[
"active_id"])
1019 $aresult =
$ilDB->queryF(
1020 "SELECT active_id FROM tst_active WHERE test_fi = %s AND tries < %s AND submitted = %s",
1021 array(
'integer',
'integer',
'integer'),
1024 while ($row =
$ilDB->fetchAssoc($aresult)) {
1026 "UPDATE tst_active SET submitted = %s, submittimestamp = %s WHERE active_id = %s",
1027 array(
'integer',
'timestamp',
'integer'),
1028 array(0,
null, $row[
"active_id"])
1033 $aresult =
$ilDB->queryF(
1034 "SELECT active_id FROM tst_active WHERE test_fi = %s AND submitted = %s",
1035 array(
'integer',
'integer'),
1038 while ($row =
$ilDB->fetchAssoc($aresult)) {
1040 "UPDATE tst_active SET submitted = %s, submittimestamp = %s WHERE active_id = %s",
1041 array(
'integer',
'timestamp',
'integer'),
1042 array(0,
null, $row[
"active_id"])
1053 $newsItem->setContext($this->
getId(),
'tst');
1055 $newsItem->setTitle(
'new_test_online');
1056 $newsItem->setContentIsLangVar(
true);
1057 $newsItem->setContent(
'');
1058 $newsItem->setUserId(
$ilUser->getId());
1060 $newsItem->create();
1067 $newsItem->setTitle(
'new_test_online');
1068 $newsItem->setContentIsLangVar(
true);
1069 $newsItem->setContent(
'');
1070 $newsItem->update();
1075 if ($this->ref_id) {
1088 $item->update($this->ref_id);
1091 if (!$properties_only) {
1096 $this->mark_schema->saveToDb($this->test_id);
1105 $oldquestions = array();
1107 $result =
$ilDB->queryF(
1108 "SELECT question_fi FROM tst_test_question WHERE test_fi = %s ORDER BY sequence",
1112 if ($result->numRows() > 0) {
1113 while ($row =
$ilDB->fetchAssoc($result)) {
1114 array_push($oldquestions, $row[
"question_fi"]);
1120 $currentQuestionsObligationsQuery =
'SELECT question_fi, obligatory FROM tst_test_question WHERE test_fi = %s';
1121 $rset =
$ilDB->queryF($currentQuestionsObligationsQuery, array(
'integer'), array($this->
getTestId()));
1122 while ($row =
$ilDB->fetchAssoc($rset)) {
1123 $obligatoryQuestionState[$row[
'question_fi']] = $row[
'obligatory'];
1126 $affectedRows =
$ilDB->manipulateF(
1127 "DELETE FROM tst_test_question WHERE test_fi = %s",
1132 foreach ($this->questions as
$key => $value) {
1134 if (!isset($obligatoryQuestionState[$value]) || is_null($obligatoryQuestionState[$value])) {
1135 $obligatoryQuestionState[$value] = 0;
1139 $next_id =
$ilDB->nextId(
'tst_test_question');
1140 $ilDB->insert(
'tst_test_question', array(
1141 'test_question_id' => array(
'integer', $next_id),
1142 'test_fi' => array(
'integer', $this->
getTestId()),
1143 'question_fi' => array(
'integer', $value),
1144 'sequence' => array(
'integer',
$key),
1145 'obligatory' => array(
'integer', $obligatoryQuestionState[$value]),
1146 'tstamp' => array(
'integer', time())
1150 $result =
$ilDB->queryF(
1151 "SELECT question_fi FROM tst_test_question WHERE test_fi = %s ORDER BY sequence",
1155 $newquestions = array();
1156 if ($result->numRows() > 0) {
1157 while ($row =
$ilDB->fetchAssoc($result)) {
1158 array_push($newquestions, $row[
"question_fi"]);
1161 foreach ($oldquestions as
$index => $question_id) {
1162 if (strcmp($newquestions[
$index], $question_id) != 0) {
1163 $pos = array_search($question_id, $newquestions);
1164 if ($pos ===
false) {
1171 foreach ($newquestions as
$index => $question_id) {
1172 if (array_search($question_id, $oldquestions) ===
false) {
1188 $result =
$ilDB->queryF(
1189 'SELECT copy_id FROM tst_rnd_cpy WHERE tst_fi = %s',
1193 return $result->numRows() > 0;
1204 int $nr_of_questions,
1211 $rbacsystem =
$DIC[
'rbacsystem'];
1215 if (($questionpool != 0) && (!$use_obj_id)) {
1220 $result =
$ilDB->queryF(
1221 "SELECT qpl_questions.original_id FROM qpl_questions, tst_test_question WHERE qpl_questions.question_id = tst_test_question.question_fi AND qpl_questions.tstamp > 0 AND tst_test_question.test_fi = %s",
1225 $original_ids = array();
1226 $paramtypes = array();
1227 $paramvalues = array();
1228 while ($row =
$ilDB->fetchAssoc($result)) {
1229 array_push($original_ids, $row[
'original_id']);
1234 if (($questionpool == 0) && (!is_array($qpls))) {
1236 if (count($available_pools)) {
1237 $available =
" AND " .
$ilDB->in(
'obj_fi', $available_pools,
false,
'integer');
1243 $constraint_qpls =
"";
1244 $result_array = array();
1245 if ($questionpool == 0) {
1246 if (is_array($qpls)) {
1247 if (count($qpls) > 0) {
1248 $constraint_qpls =
" AND " .
$ilDB->in(
'obj_fi', $qpls,
false,
'integer');
1253 $original_clause =
"";
1254 if (count($original_ids)) {
1255 $original_clause =
" AND " .
$ilDB->in(
'question_id', $original_ids,
true,
'integer');
1258 if ($questionpool == 0) {
1259 $result =
$ilDB->queryF(
1260 "SELECT question_id FROM qpl_questions WHERE original_id IS NULL $available $constraint_qpls AND owner > %s AND complete = %s $original_clause",
1261 array(
'integer',
'text'),
1265 $result =
$ilDB->queryF(
1266 "SELECT question_id FROM qpl_questions WHERE original_id IS NULL AND obj_fi = %s AND owner > %s AND complete = %s $original_clause",
1267 array(
'integer',
'integer',
'text'),
1268 array($questionpool, 0,
"1")
1271 $found_ids = array();
1272 while ($row =
$ilDB->fetchAssoc($result)) {
1273 array_push($found_ids, $row[
'question_id']);
1275 $nr_of_questions = ($nr_of_questions > count($found_ids)) ? count($found_ids) : $nr_of_questions;
1276 if ($nr_of_questions == 0) {
1279 $rand_keys = array_rand($found_ids, $nr_of_questions);
1281 if (is_array($rand_keys)) {
1282 foreach ($rand_keys as
$key) {
1283 $result[$found_ids[
$key]] = $found_ids[
$key];
1286 $result[$found_ids[$rand_keys]] = $found_ids[$rand_keys];
1299 $result =
$ilDB->queryF(
1300 "SELECT test_result_id FROM tst_test_result WHERE active_fi = %s AND pass = %s",
1301 array(
'integer',
'integer'),
1302 array($active_id, $pass)
1304 return $result->numRows();
1315 $result =
$ilDB->queryF(
1316 "SELECT test_random_question_id FROM tst_test_rnd_qst WHERE active_fi = %s AND pass = %s",
1317 array(
'integer',
'integer'),
1318 array($active_id, $pass)
1320 return ($result->numRows() > 0) ?
true :
false;
1328 $result =
$ilDB->queryF(
1329 "SELECT * FROM tst_tests WHERE obj_fi = %s",
1331 array($this->
getId())
1333 if ($result->numRows() == 1) {
1335 $this->setTestId(
$data->test_id);
1337 if (
$data->author) {
1338 if (strlen($this->getAuthor()) == 0) {
1339 $this->saveAuthorToMetadata(
$data->author);
1341 $this->setAuthor(
$data->author);
1344 $this->setIntroductionEnabled(
$data->intro_enabled);
1346 $this->setShowInfo(
$data->showinfo);
1348 $this->setForceJS(
$data->forcejs);
1349 $this->setCustomStyle(
$data->customstyle);
1350 $this->setShowFinalStatement(
$data->showfinalstatement);
1351 $this->setSequenceSettings(
$data->sequence_settings);
1352 $this->setInstantFeedbackSolution(
$data->instant_verification);
1353 $this->setAnswerFeedbackPoints(
$data->answer_feedback_points);
1354 $this->setAnswerFeedback(
$data->answer_feedback);
1355 $this->setAnonymity(
$data->anonymity);
1356 $this->setShowCancel(
$data->show_cancel);
1357 $this->setShowMarker(
$data->show_marker);
1358 $this->setFixedParticipants(
$data->fixed_participants);
1359 $this->setNrOfTries(
$data->nr_of_tries);
1360 $this->setBlockPassesAfterPassedEnabled((
bool)
$data->block_after_passed);
1361 $this->setKiosk(
$data->kiosk);
1362 $this->setUsePreviousAnswers(
$data->use_previous_answers);
1363 $this->setRedirectionMode(
$data->redirection_mode);
1364 $this->setRedirectionUrl(
$data->redirection_url);
1365 $this->setTitleOutput(
$data->title_output);
1366 $this->setProcessingTime(
$data->processing_time);
1367 $this->setEnableProcessingTime(
$data->enable_processing_time);
1368 $this->setResetProcessingTime(
$data->reset_processing_time);
1369 $this->setReportingDate(
$data->reporting_date);
1370 $this->setShuffleQuestions(
$data->shuffle_questions);
1371 $this->setStartingTimeEnabled(
$data->starting_time_enabled);
1372 $this->setStartingTime(
$data->starting_time);
1373 $this->setEndingTimeEnabled(
$data->ending_time_enabled);
1374 $this->setEndingTime(
$data->ending_time);
1375 $this->setListOfQuestionsSettings(
$data->show_summary);
1376 $this->setECTSOutput(
$data->ects_output);
1377 $this->setECTSGrades(
1379 "A" =>
$data->ects_a,
1380 "B" =>
$data->ects_b,
1381 "C" =>
$data->ects_c,
1382 "D" =>
$data->ects_d,
1383 "E" =>
$data->ects_e
1386 $this->setECTSFX(
$data->ects_fx);
1387 $this->mark_schema->flush();
1388 $this->mark_schema->loadFromDb($this->getTestId());
1389 $this->setMailNotification(
$data->mailnotification);
1390 $this->setMailNotificationType(
$data->mailnottype);
1391 $this->setPasswordEnabled(
$data->password_enabled);
1392 $this->setPassword(
$data->password);
1393 $this->setLimitUsersEnabled(
$data->limit_users_enabled);
1394 $this->setAllowedUsers(
$data->allowedusers);
1395 $this->setAllowedUsersTimeGap(
$data->alloweduserstimegap);
1396 $this->setObligationsEnabled(
$data->obligations_enabled);
1397 $this->setOfferingQuestionHintsEnabled(
$data->offer_question_hints);
1398 $this->setEnabledViewMode(
$data->enabled_view_mode);
1399 $this->setTemplate(
$data->template_id);
1400 $this->setOldOnlineStatus(!$this->getOfflineStatus());
1401 $this->setSpecificAnswerFeedback((
int)
$data->specific_feedback);
1402 $this->setAutosave((
bool)
$data->autosave);
1403 $this->setAutosaveIval((
int)
$data->autosave_ival);
1404 $this->setEnableExamview((
bool)
$data->enable_examview);
1405 $this->setShowExamviewHtml((
bool)
$data->show_examview_html);
1406 $this->setShowExamviewPdf((
bool)
$data->show_examview_pdf);
1407 $this->setEnableArchiving((
bool)
$data->enable_archiving);
1408 $this->setShowExamIdInTestPassEnabled((
bool)
$data->examid_in_test_pass);
1409 $this->setSignSubmission((
bool)
$data->sign_submission);
1410 $this->setQuestionSetType(
$data->question_set_type);
1411 $this->setCharSelectorAvailability((
int)
$data->char_selector_availability);
1412 $this->setCharSelectorDefinition(
$data->char_selector_definition);
1413 $this->setSkillServiceEnabled((
bool)
$data->skill_service);
1414 $this->setShowGradingStatusEnabled((
bool)
$data->show_grading_status);
1415 $this->setShowGradingMarkEnabled((
bool)
$data->show_grading_mark);
1416 $this->setFollowupQuestionAnswerFixationEnabled((
bool)
$data->follow_qst_answer_fixation);
1417 $this->setInstantFeedbackAnswerFixationEnabled((
bool)
$data->inst_fb_answer_fixation);
1418 $this->setForceInstantFeedbackEnabled((
bool)
$data->force_inst_fb);
1419 $this->setTestFinalBroken((
bool)
$data->broken);
1420 $this->setPassWaiting(
$data->pass_waiting);
1421 $this->loadQuestions();
1425 if (isset($this->ref_id)) {
1427 switch ($activation[
"timing_type"]) {
1429 $this->setActivationLimited(
true);
1430 $this->setActivationStartingTime($activation[
"timing_start"]);
1431 $this->setActivationEndingTime($activation[
"timing_end"]);
1432 $this->setActivationVisibility($activation[
"visible"]);
1436 $this->setActivationLimited(
false);
1454 $tags_trafo = $this->
refinery->string()->stripTags();
1456 $this->questions = array();
1457 if ($this->isRandomTest()) {
1458 if (strcmp($active_id,
"") == 0) {
1459 $active_id = $this->getActiveIdOfUser(
$ilUser->getId());
1461 if (is_null($pass)) {
1462 $pass = self::_getPass($active_id);
1464 $result =
$ilDB->queryF(
1465 "SELECT tst_test_rnd_qst.* FROM tst_test_rnd_qst, qpl_questions WHERE tst_test_rnd_qst.active_fi = %s AND qpl_questions.question_id = tst_test_rnd_qst.question_fi AND tst_test_rnd_qst.pass = %s ORDER BY sequence",
1466 array(
'integer',
'integer'),
1467 array($active_id, $pass)
1473 if ($result->numRows() == 0) {
1474 $result =
$ilDB->queryF(
1475 "SELECT tst_test_rnd_qst.* FROM tst_test_rnd_qst, qpl_questions WHERE tst_test_rnd_qst.active_fi = %s AND qpl_questions.question_id = tst_test_rnd_qst.question_fi AND tst_test_rnd_qst.pass = 0 ORDER BY sequence",
1481 $result =
$ilDB->queryF(
1482 "SELECT tst_test_question.* FROM tst_test_question, qpl_questions WHERE tst_test_question.test_fi = %s AND qpl_questions.question_id = tst_test_question.question_fi ORDER BY sequence",
1484 array($this->test_id)
1488 if ($this->test_id !== -1) {
1491 $this->questions[
$index++] =
$data[
"question_fi"];
1498 return $this->introductionEnabled;
1506 $this->introductionEnabled = $introductionEnabled;
1511 return $this->introduction;
1516 $this->introduction = $this->getHtmlQuestionContentPurifier()->purify($introduction);
1521 $this->_finalstatement = $a_statement;
1533 $this->_showinfo = ($a_info) ? 1 : 0;
1545 $this->_forcejs = ($a_js) ? 1 : 0;
1557 $this->_customStyle = $a_customStyle;
1566 return (strlen($this->_customStyle)) ? $this->_customStyle :
null;
1578 $this->_showfinalstatement = ($show) ? 1 : 0;
1583 return $this->_finalstatement;
1595 return ($this->_showinfo) ? 1 : 0;
1607 return ($this->_forcejs) ? 1 : 0;
1619 return ($this->_showfinalstatement) ? 1 : 0;
1631 return $this->test_id;
1636 return ($this->ects_output) ? 1 : 0;
1641 $this->ects_output = $a_ects_output ? 1 : 0;
1646 return $this->ects_fx;
1651 $this->ects_fx = (float) str_replace(
",",
".", $a_ects_fx);
1656 return $this->ects_grades;
1661 $this->ects_grades = $a_ects_grades;
1671 return ($this->sequence_settings) ? $this->sequence_settings : 0;
1681 $this->sequence_settings = $sequence_settings;
1686 return (
bool) $this->getSequenceSettings();
1691 $this->setSequenceSettings((
int) $postponingEnabled);
1702 switch ($instant_feedback) {
1704 $this->instant_verification = 1;
1707 $this->instant_verification = 0;
1720 switch ($answer_feedback) {
1722 $this->answer_feedback = 1;
1725 $this->answer_feedback = 0;
1732 switch ($generic_answer_feedback) {
1734 $this->answer_feedback = 1;
1737 $this->answer_feedback = 0;
1750 switch ($answer_feedback_points) {
1752 $this->answer_feedback_points = 1;
1755 $this->answer_feedback_points = 0;
1766 if (!$reporting_date) {
1767 $this->reporting_date =
'';
1768 $this->setECTSOutput(
false);
1770 $this->reporting_date = $reporting_date;
1774 public const SCORE_REPORTING_DISABLED = 0;
1775 public const SCORE_REPORTING_FINISHED = 1;
1776 public const SCORE_REPORTING_IMMIDIATLY = 2;
1777 public const SCORE_REPORTING_DATE = 3;
1778 public const SCORE_REPORTING_AFTER_PASSED = 4;
1782 if ($this->getTestId() !== -1) {
1783 return $this->getScoreSettings()->getResultSummarySettings()->getScoreReporting();
1790 switch ($this->getScoreReporting()) {
1791 case self::SCORE_REPORTING_FINISHED:
1792 case self::SCORE_REPORTING_IMMIDIATLY:
1793 case self::SCORE_REPORTING_DATE:
1794 case self::SCORE_REPORTING_AFTER_PASSED:
1798 case self::SCORE_REPORTING_DISABLED:
1814 return ($this->instant_verification) ? $this->instant_verification : 0;
1827 return ($this->answer_feedback) ? $this->answer_feedback : 0;
1838 return ($this->answer_feedback) ? $this->answer_feedback : 0;
1850 return ($this->answer_feedback_points) ? $this->answer_feedback_points : 0;
1862 return $this->getScoreSettings()->getScoringSettings()->getCountSystem();
1876 $result =
$ilDB->queryF(
1877 "SELECT tst_tests.count_system FROM tst_tests, tst_active WHERE tst_active.active_id = %s AND tst_active.test_fi = tst_tests.test_id",
1881 if ($result->numRows()) {
1882 $row =
$ilDB->fetchAssoc($result);
1883 return $row[
"count_system"];
1897 return $this->getScoreSettings()->getScoringSettings()->getScoreCutting();
1909 return $this->getScoreSettings()->getScoringSettings()->getPassScoring();
1923 $result =
$ilDB->queryF(
1924 "SELECT tst_tests.pass_scoring FROM tst_tests, tst_active WHERE tst_tests.test_id = tst_active.test_fi AND tst_active.active_id = %s",
1928 if ($result->numRows()) {
1929 $row =
$ilDB->fetchAssoc($result);
1930 return $row[
"pass_scoring"];
1946 $result =
$ilDB->queryF(
1947 "SELECT tst_tests.score_cutting FROM tst_tests, tst_active WHERE tst_active.active_id = %s AND tst_tests.test_id = tst_active.test_fi",
1951 if ($result->numRows()) {
1952 $row =
$ilDB->fetchAssoc($result);
1953 return $row[
"score_cutting"];
1968 return $this->getScoreSettings()->getResultSummarySettings()->getReportingDate();
1980 return ($this->nr_of_tries) ? $this->nr_of_tries : 0;
1988 return $this->blockPassesAfterPassedEnabled;
1996 $this->blockPassesAfterPassedEnabled = $blockPassesAfterPassedEnabled;
2008 return ($this->_kiosk) ? $this->_kiosk : 0;
2021 $this->_kiosk = $kiosk;
2033 if (($this->_kiosk & 1) > 0) {
2050 $this->_kiosk = $this->_kiosk | 1;
2052 if ($this->getKioskMode()) {
2053 $this->_kiosk = $this->_kiosk ^ 1;
2067 if (($this->_kiosk & 2) > 0) {
2083 $this->_kiosk = $this->_kiosk | 2;
2085 if ($this->getShowKioskModeTitle()) {
2086 $this->_kiosk = $this->_kiosk ^ 2;
2100 if (($this->_kiosk & 4) > 0) {
2115 if ($a_participant) {
2116 $this->_kiosk = $this->_kiosk | 4;
2118 if ($this->getShowKioskModeParticipant()) {
2119 $this->_kiosk = $this->_kiosk ^ 4;
2133 return ($this->use_previous_answers) ? $this->use_previous_answers : 0;
2145 return ($this->title_output) ? $this->title_output : 0;
2161 $result =
$ilDB->queryF(
2162 "SELECT tst_tests.title_output FROM tst_tests, tst_active WHERE tst_tests.test_id = tst_active.test_fi AND tst_active.active_id = %s",
2166 if ($result->numRows()) {
2167 $row =
$ilDB->fetchAssoc($result);
2168 return $row[
"title_output"];
2175 $result = $this->db->queryF(
2176 "SELECT tst_tests.use_previous_answers FROM tst_tests, tst_active WHERE tst_tests.test_id = tst_active.test_fi AND tst_active.active_id = %s",
2180 if ($result->numRows()) {
2181 $row = $this->db->fetchAssoc($result);
2182 $test_allows_reuse = $row[
"use_previous_answers"];
2185 if ($test_allows_reuse ===
'1') {
2186 $res = $this->
user->getPref(
"tst_use_previous_answers");
2203 return (strlen($this->processing_time)) ? $this->processing_time :
null;
2211 if (strlen($this->processing_time)) {
2212 if (preg_match(
"/(\d{2}):(\d{2}):(\d{2})/is", $this->processing_time, $matches)) {
2213 if ((
int) $matches[1] + (
int) $matches[2] + (
int) $matches[3] == 0) {
2214 return $this->getEstimatedWorkingTime();
2217 'hh' => $matches[1],
2218 'mm' => $matches[2],
2219 'ss' => $matches[3],
2224 return $this->getEstimatedWorkingTime();
2229 if (strlen($this->processing_time)) {
2230 if (preg_match(
"/(\d{2}):(\d{2}):(\d{2})/is", $this->processing_time, $matches)) {
2231 return ($matches[1] * 60) + $matches[2];
2235 return self::DEFAULT_PROCESSING_TIME_MINUTES;
2247 if (preg_match(
"/(\d{2}):(\d{2}):(\d{2})/", $this->getProcessingTime(), $matches)) {
2248 $extratime = $this->getExtraTime($active_id) * 60;
2249 return ($matches[1] * 3600) + ($matches[2] * 60) + $matches[3] + $extratime;
2264 if ($this->getEndingTime() != 0) {
2265 $ending = $this->getEndingTime();
2267 return $ending - $now;
2282 return ($this->enable_processing_time) ? $this->enable_processing_time : 0;
2294 return ($this->reset_processing_time) ? $this->reset_processing_time : 0;
2299 return $this->starting_time_enabled;
2307 $this->starting_time_enabled = $starting_time_enabled;
2319 return ($this->starting_time != 0) ? $this->starting_time : 0;
2331 $this->starting_time = $starting_time;
2336 return $this->ending_time_enabled;
2344 $this->ending_time_enabled = $ending_time_enabled;
2356 return ($this->ending_time != 0) ? $this->ending_time : 0;
2368 $this->ending_time = $ending_time;
2380 $this->nr_of_tries = $nr_of_tries;
2392 if ($use_previous_answers) {
2393 $this->use_previous_answers = 1;
2395 $this->use_previous_answers = 0;
2401 $this->redirection_mode = $redirection_mode;
2405 return $this->redirection_mode;
2409 $this->redirection_url = $redirection_url;
2413 return $this->redirection_url;
2425 switch ($title_output) {
2427 $this->title_output = 1;
2430 $this->title_output = 2;
2433 $this->title_output = 0;
2447 $this->processing_time = $processing_time;
2452 $this->processing_time = sprintf(
"%02d:%02d:00", floor($minutes / 60), $minutes % 60);
2465 $this->enable_processing_time =
"1";
2467 $this->enable_processing_time =
"0";
2481 $this->reset_processing_time = 1;
2483 $this->reset_processing_time = 0;
2492 return $this->passwordEnabled;
2500 $this->passwordEnabled = $passwordEnabled;
2505 return (strlen($this->password)) ? $this->password :
null;
2517 $this->password = $a_password;
2525 return $this->pass_waiting ??
'';
2533 $this->pass_waiting = $pass_waiting;
2540 if (array_sum(explode(
':', $this->getPassWaiting())) > 0) {
2559 $DIC[
'component.repository'],
2563 foreach ($activeIds as $activeId) {
2565 $passSelector->setActiveId($activeId);
2567 foreach ($passSelector->getExistingPasses() as $pass) {
2568 $testSequence = $testSequenceFactory->getSequenceByActiveIdAndPass($activeId, $pass);
2569 $testSequence->loadFromDb();
2571 $testSequence->removeQuestion($questionId, $reindexedSequencePositionMap);
2572 $testSequence->saveToDb();
2582 foreach ($removeQuestionIds as $value) {
2583 $this->removeQuestion((
int) $value);
2586 $this->reindexFixedQuestionOrdering();
2592 $question = self::_instanciateQuestion($question_id);
2599 $question->delete($question_id);
2600 }
catch (InvalidArgumentException
$e) {
2601 $this->log->error(
$e->getMessage());
2602 $this->log->error(
$e->getTraceAsString());
2616 $this->removeTestResultsByUserIds($userIds);
2623 $participantData->setUserIdsFilter($userIds);
2624 $participantData->load($this->getTestId());
2626 $this->removeTestActives($participantData->getActiveIds());
2638 $testLP->setTestObject($this);
2639 $testLP->resetLPDataForUserIds($participantData->
getUserIds(),
false);
2643 $this->removeTestActives($participantData->
getActiveIds());
2653 $participantData->setUserIdsFilter($userIds);
2654 $participantData->load($this->getTestId());
2656 $IN_userIds =
$ilDB->in(
'usr_id', $participantData->getUserIds(),
false,
'integer');
2658 "DELETE FROM usr_pref WHERE $IN_userIds AND keyword = %s",
2660 array(
"tst_password_" . $this->getTestId())
2663 if (count($participantData->getActiveIds())) {
2664 $this->removeTestResultsByActiveIds($participantData->getActiveIds());
2672 $IN_activeIds =
$ilDB->in(
'active_fi', $activeIds,
false,
'integer');
2674 $ilDB->manipulate(
"DELETE FROM tst_solutions WHERE $IN_activeIds");
2675 $ilDB->manipulate(
"DELETE FROM tst_qst_solved WHERE $IN_activeIds");
2676 $ilDB->manipulate(
"DELETE FROM tst_test_result WHERE $IN_activeIds");
2677 $ilDB->manipulate(
"DELETE FROM tst_pass_result WHERE $IN_activeIds");
2678 $ilDB->manipulate(
"DELETE FROM tst_result_cache WHERE $IN_activeIds");
2679 $ilDB->manipulate(
"DELETE FROM tst_sequence WHERE $IN_activeIds");
2680 $ilDB->manipulate(
"DELETE FROM tst_times WHERE $IN_activeIds");
2682 if ($this->isRandomTest()) {
2683 $ilDB->manipulate(
"DELETE FROM tst_test_rnd_qst WHERE $IN_activeIds");
2684 } elseif ($this->isDynamicTest()) {
2685 $ilDB->manipulate(
"DELETE FROM tst_seq_qst_tracking WHERE $IN_activeIds");
2686 $ilDB->manipulate(
"DELETE FROM tst_seq_qst_answstatus WHERE $IN_activeIds");
2687 $ilDB->manipulate(
"DELETE FROM tst_seq_qst_postponed WHERE $IN_activeIds");
2688 $ilDB->manipulate(
"DELETE FROM tst_seq_qst_checked WHERE $IN_activeIds");
2691 foreach ($activeIds as $active_id) {
2693 if (@is_dir(
CLIENT_WEB_DIR .
"/assessment/tst_" . $this->getTestId() .
"/$active_id")) {
2698 $this->logAction(sprintf($this->
lng->txtlng(
"assessment",
"log_selected_user_data_removed",
ilObjAssessmentFolder::_getLogLanguage()), $this->userLookupFullName($this->_getUserIdFromActiveId($active_id))));
2710 $IN_activeIds =
$ilDB->in(
'active_id', $activeIds,
false,
'integer');
2711 $ilDB->manipulate(
"DELETE FROM tst_active WHERE $IN_activeIds");
2727 $result =
$ilDB->queryF(
2728 "SELECT * FROM tst_test_question WHERE test_fi=%s AND question_fi=%s",
2729 array(
'integer',
'integer'),
2730 array($this->getTestId(), $question_id)
2733 if (
$data->sequence > 1) {
2735 $result =
$ilDB->queryF(
2736 "SELECT * FROM tst_test_question WHERE test_fi=%s AND sequence=%s",
2737 array(
'integer',
'integer'),
2738 array($this->getTestId(),
$data->sequence - 1)
2740 $data_previous =
$ilDB->fetchObject($result);
2743 "UPDATE tst_test_question SET sequence=%s WHERE test_question_id=%s",
2744 array(
'integer',
'integer'),
2745 array(
$data->sequence, $data_previous->test_question_id)
2749 "UPDATE tst_test_question SET sequence=%s WHERE test_question_id=%s",
2750 array(
'integer',
'integer'),
2751 array(
$data->sequence - 1,
$data->test_question_id)
2757 $this->loadQuestions();
2773 $result =
$ilDB->queryF(
2774 "SELECT * FROM tst_test_question WHERE test_fi=%s AND question_fi=%s",
2775 array(
'integer',
'integer'),
2776 array($this->getTestId(), $question_id)
2779 $result =
$ilDB->queryF(
2780 "SELECT * FROM tst_test_question WHERE test_fi=%s AND sequence=%s",
2781 array(
'integer',
'integer'),
2782 array($this->getTestId(),
$data->sequence + 1)
2784 if ($result->numRows() == 1) {
2786 $data_next =
$ilDB->fetchObject($result);
2789 "UPDATE tst_test_question SET sequence=%s WHERE test_question_id=%s",
2790 array(
'integer',
'integer'),
2791 array(
$data->sequence, $data_next->test_question_id)
2795 "UPDATE tst_test_question SET sequence=%s WHERE test_question_id=%s",
2796 array(
'integer',
'integer'),
2797 array(
$data->sequence + 1,
$data->test_question_id)
2803 $this->loadQuestions();
2815 $duplicate_id = $question->duplicate(
true,
'',
'',
'', $this->
getId());
2816 return $duplicate_id;
2832 $duplicate_id = $question_id;
2834 $duplicate_id = $this->duplicateQuestionForTest($question_id);
2838 $result =
$ilDB->queryF(
2839 "SELECT MAX(sequence) seq FROM tst_test_question WHERE test_fi=%s",
2841 array($this->getTestId())
2845 if ($result->numRows() == 1) {
2847 $sequence =
$data->seq + 1;
2850 $next_id =
$ilDB->nextId(
'tst_test_question');
2851 $affectedRows =
$ilDB->manipulateF(
2852 "INSERT INTO tst_test_question (test_question_id, test_fi, question_fi, sequence, tstamp) VALUES (%s, %s, %s, %s, %s)",
2853 array(
'integer',
'integer',
'integer',
'integer',
'integer'),
2854 array($next_id, $this->getTestId(), $duplicate_id, $sequence, time())
2856 if ($affectedRows == 1) {
2862 $affectedRows =
$ilDB->manipulateF(
2863 "DELETE FROM tst_active WHERE test_fi = %s",
2865 array($this->getTestId())
2867 $this->loadQuestions();
2868 $this->saveCompleteStatus($testQuestionSetConfig);
2869 return $duplicate_id;
2882 if ($this->getQuestionSetType() == self::QUESTION_SET_TYPE_FIXED) {
2885 $result =
$ilDB->queryF(
2886 "SELECT qpl_questions.title FROM tst_test_question, qpl_questions WHERE tst_test_question.test_fi = %s AND tst_test_question.question_fi = qpl_questions.question_id ORDER BY tst_test_question.sequence",
2888 array($this->getTestId())
2890 while ($row =
$ilDB->fetchAssoc($result)) {
2891 array_push($titles, $row[
"title"]);
2907 if ($this->getQuestionSetType() == self::QUESTION_SET_TYPE_FIXED) {
2910 $result =
$ilDB->queryF(
2911 "SELECT qpl_questions.title, qpl_questions.question_id FROM tst_test_question, qpl_questions WHERE tst_test_question.test_fi = %s AND tst_test_question.question_fi = qpl_questions.question_id ORDER BY tst_test_question.sequence",
2913 array($this->getTestId())
2915 while ($row =
$ilDB->fetchAssoc($result)) {
2916 $titles[$row[
'question_id']] = $row[
"title"];
2934 if ($this->getTitleOutput() !== 2) {
2938 if ($this->getTitleOutput() === 2 && isset($nr)) {
2939 return $this->
lng->txt(
"ass_question") .
' ' . $nr;
2942 return $this->
lng->txt(
"ass_question");
2959 $result =
$ilDB->queryF(
2960 "SELECT qpl_questions.*, qpl_qst_type.type_tag FROM qpl_questions, qpl_qst_type WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id",
2964 $row =
$ilDB->fetchObject($result);
2980 $existing_questions = array();
2981 $active_id = $this->getActiveIdOfUser(
$ilUser->getId());
2982 if ($this->isRandomTest()) {
2983 if (is_null($pass)) {
2986 $result =
$ilDB->queryF(
2987 "SELECT qpl_questions.original_id FROM qpl_questions, tst_test_rnd_qst WHERE tst_test_rnd_qst.active_fi = %s AND tst_test_rnd_qst.question_fi = qpl_questions.question_id AND tst_test_rnd_qst.pass = %s",
2988 array(
'integer',
'integer'),
2989 array($active_id, $pass)
2992 $result =
$ilDB->queryF(
2993 "SELECT qpl_questions.original_id FROM qpl_questions, tst_test_question WHERE tst_test_question.test_fi = %s AND tst_test_question.question_fi = qpl_questions.question_id",
2995 array($this->getTestId())
2998 while (
$data =
$ilDB->fetchObject($result)) {
2999 if (
$data->original_id ===
null) {
3003 array_push($existing_questions,
$data->original_id);
3005 return $existing_questions;
3020 if ($question_id < 1) {
3023 $result =
$ilDB->queryF(
3024 "SELECT type_tag FROM qpl_questions, qpl_qst_type WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id",
3028 if ($result->numRows() == 1) {
3030 return $data->type_tag;
3047 $next_id =
$ilDB->nextId(
'tst_times');
3048 $affectedRows =
$ilDB->manipulateF(
3049 "INSERT INTO tst_times (times_id, active_fi, started, finished, pass, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
3050 array(
'integer',
'integer',
'timestamp',
'timestamp',
'integer',
'integer'),
3051 array($next_id, $active_id, date(
"Y-m-d H:i:s"), date(
"Y-m-d H:i:s"), $pass, time())
3067 $affectedRows =
$ilDB->manipulateF(
3068 "UPDATE tst_times SET finished = %s, tstamp = %s WHERE times_id = %s",
3069 array(
'timestamp',
'integer',
'integer'),
3070 array(date(
'Y-m-d H:i:s'), time(), $times_id)
3086 if (is_null($pass)) {
3087 $result =
$ilDB->queryF(
3088 "SELECT question_fi FROM tst_solutions WHERE active_fi = %s AND pass = %s GROUP BY question_fi",
3089 array(
'integer',
'integer'),
3090 array($active_id, 0)
3093 $result =
$ilDB->queryF(
3094 "SELECT question_fi FROM tst_solutions WHERE active_fi = %s AND pass = %s GROUP BY question_fi",
3095 array(
'integer',
'integer'),
3096 array($active_id, $pass)
3099 $result_array = array();
3100 while ($row =
$ilDB->fetchAssoc($result)) {
3101 array_push($result_array, $row[
"question_fi"]);
3103 return $result_array;
3117 return ((($currentpass > 0) && ($num == 0)) || $this->isTestFinished($active_id)) ?
true :
false;
3132 $result_array = array();
3133 if ($this->isRandomTest()) {
3134 $active_id = $this->getActiveIdOfUser(
$ilUser->getId());
3135 $this->loadQuestions($active_id, $pass);
3136 if (count($this->questions) == 0) {
3137 return $result_array;
3139 if (is_null($pass)) {
3140 $pass = self::_getPass($active_id);
3142 $result =
$ilDB->queryF(
3143 "SELECT qpl_questions.* FROM qpl_questions, tst_test_rnd_qst WHERE tst_test_rnd_qst.question_fi = qpl_questions.question_id AND tst_test_rnd_qst.active_fi = %s AND tst_test_rnd_qst.pass = %s AND " .
$ilDB->in(
'qpl_questions.question_id', $this->questions,
false,
'integer'),
3144 array(
'integer',
'integer'),
3145 array($active_id, $pass)
3148 if (count($this->questions) == 0) {
3149 return $result_array;
3151 $result =
$ilDB->query(
"SELECT qpl_questions.* FROM qpl_questions, tst_test_question WHERE tst_test_question.question_fi = qpl_questions.question_id AND " .
$ilDB->in(
'qpl_questions.question_id', $this->questions,
false,
'integer'));
3153 while ($row =
$ilDB->fetchAssoc($result)) {
3154 $result_array[$row[
"question_id"]] = $row;
3156 return $result_array;
3178 if (is_array($tst_access_code) &&
3180 isset($tst_access_code[$this->getTestId()]) &&
3181 $tst_access_code[$this->getTestId()] !==
'') {
3182 $result =
$ilDB->queryF(
3183 'SELECT active_id FROM tst_active WHERE user_fi = %s AND test_fi = %s AND anonymous_id = %s',
3184 [
'integer',
'integer',
'text'],
3185 [$user_id, $this->test_id, $tst_access_code[$this->getTestId()]]
3187 } elseif ((
string) $anonymous_id !==
'') {
3188 $result =
$ilDB->queryF(
3189 'SELECT active_id FROM tst_active WHERE user_fi = %s AND test_fi = %s AND anonymous_id = %s',
3190 [
'integer',
'integer',
'text'],
3191 [$user_id, $this->test_id, $anonymous_id]
3197 $result =
$ilDB->queryF(
3198 'SELECT active_id FROM tst_active WHERE user_fi = %s AND test_fi = %s',
3199 [
'integer',
'integer'],
3200 [$user_id, $this->test_id]
3204 if ($result->numRows()) {
3205 $row =
$ilDB->fetchAssoc($result);
3206 return (
int) $row[
'active_id'];
3224 $result =
$ilDB->queryF(
3225 "SELECT tst_active.active_id FROM tst_active WHERE user_fi = %s AND test_fi = %s",
3226 array(
'integer',
'integer'),
3227 array($user_id, $test_id)
3229 if ($result->numRows()) {
3230 $row =
$ilDB->fetchAssoc($result);
3231 return $row[
"active_id"];
3245 $keys = array_keys($array);
3263 bool $ordered_sequence =
false,
3264 bool $considerHiddenQuestions =
true,
3265 bool $considerOptionalQuestions =
true
3268 $tree =
$DIC[
'tree'];
3272 $component_repository =
$DIC[
'component.repository'];
3274 $results = $this->getResultsForActiveId($active_id);
3276 if ($pass ===
null) {
3281 $testSession = $testSessionFactory->getSession($active_id);
3284 $testSequence = $testSequenceFactory->getSequenceByActiveIdAndPass($active_id, $pass);
3286 if ($this->isDynamicTest()) {
3288 $dynamicQuestionSetConfig->loadFromDb();
3290 $testSequence->loadFromDb($dynamicQuestionSetConfig);
3293 $sequence = $testSequence->getUserSequenceQuestions();
3295 $testSequence->setConsiderHiddenQuestionsEnabled($considerHiddenQuestions);
3296 $testSequence->setConsiderOptionalQuestionsEnabled($considerOptionalQuestions);
3298 $testSequence->loadFromDb();
3299 $testSequence->loadQuestions();
3301 if ($ordered_sequence) {
3302 $sequence = $testSequence->getOrderedSequenceQuestions();
3304 $sequence = $testSequence->getUserSequenceQuestions();
3311 SELECT tst_test_result.question_fi,
3312 tst_test_result.points reached,
3313 tst_test_result.hint_count requested_hints,
3314 tst_test_result.hint_points hint_points,
3315 tst_test_result.answered answered
3317 FROM tst_test_result
3319 LEFT JOIN tst_solutions
3320 ON tst_solutions.active_fi = tst_test_result.active_fi
3321 AND tst_solutions.question_fi = tst_test_result.question_fi
3323 WHERE tst_test_result.active_fi = %s
3324 AND tst_test_result.pass = %s
3327 $solutionresult =
$ilDB->queryF(
3329 array(
'integer',
'integer'),
3330 array($active_id, $pass)
3333 while ($row =
$ilDB->fetchAssoc($solutionresult)) {
3334 $arrResults[ $row[
'question_fi'] ] = $row;
3337 $numWorkedThrough = count($arrResults);
3339 $IN_question_ids =
$ilDB->in(
'qpl_questions.question_id', $sequence,
false,
'integer');
3342 SELECT qpl_questions.*,
3343 qpl_qst_type.type_tag,
3344 qpl_sol_sug.question_fi has_sug_sol
3349 LEFT JOIN qpl_sol_sug
3350 ON qpl_sol_sug.question_fi = qpl_questions.question_id
3352 WHERE qpl_qst_type.question_type_id = qpl_questions.question_type_fi
3353 AND $IN_question_ids
3362 $obligationsAnswered =
true;
3364 while ($row =
$ilDB->fetchAssoc($result)) {
3365 if (!isset($arrResults[ $row[
'question_id'] ])) {
3366 $percentvalue = 0.0;
3369 $row[
'points'] ? $arrResults[$row[
'question_id']][
'reached'] / $row[
'points'] : 0
3372 if ($percentvalue < 0) {
3373 $percentvalue = 0.0;
3379 "max" => round($row[
'points'], 2),
3380 "reached" => round($arrResults[$row[
'question_id']][
'reached'] ?? 0, 2),
3381 'requested_hints' => $arrResults[$row[
'question_id']][
'requested_hints'] ?? 0,
3382 'hint_points' => $arrResults[$row[
'question_id']][
'hint_points'] ?? 0,
3383 "percent" => sprintf(
"%2.2f ", ($percentvalue) * 100) .
"%",
3385 "type" => $row[
"type_tag"],
3386 "qid" => $row[
'question_id'],
3387 "original_id" => $row[
"original_id"],
3388 "workedthrough" => isset($arrResults[$row[
'question_id']]) ? 1 : 0,
3389 'answered' => $arrResults[$row[
'question_id']][
'answered'] ?? 0
3392 if (!isset($arrResults[ $row[
'question_id'] ][
'answered']) || !$arrResults[ $row[
'question_id'] ][
'answered']) {
3393 $obligationsAnswered =
false;
3396 $unordered[ $row[
'question_id'] ] =
$data;
3401 $numQuestionsTotal = count($unordered);
3405 $pass_requested_hints = 0;
3406 $pass_hint_points = 0;
3411 foreach ($sequence as $qid) {
3414 $pass_max += round($unordered[$qid][
'max'], 2);
3415 $pass_reached += round($unordered[$qid][
'reached'], 2);
3416 $pass_requested_hints += $unordered[$qid][
'requested_hints'];
3417 $pass_hint_points += $unordered[$qid][
'hint_points'];
3421 $unordered[$qid][
'nr'] =
$key;
3422 array_push($found, $unordered[$qid]);
3430 if ($this->getScoreCutting() == 1) {
3431 if (
$results[
'reached_points'] < 0) {
3435 if ($pass_reached < 0) {
3440 $found[
'pass'][
'total_max_points'] = $pass_max;
3441 $found[
'pass'][
'total_reached_points'] = $pass_reached;
3442 $found[
'pass'][
'total_requested_hints'] = $pass_requested_hints;
3443 $found[
'pass'][
'total_hint_points'] = $pass_hint_points;
3444 $found[
'pass'][
'percent'] = ($pass_max > 0) ? $pass_reached / $pass_max : 0;
3445 $found[
'pass'][
'obligationsAnswered'] = $obligationsAnswered;
3446 $found[
'pass'][
'num_workedthrough'] = $numWorkedThrough;
3447 $found[
'pass'][
'num_questions_total'] = $numQuestionsTotal;
3449 $found[
"test"][
"total_max_points"] =
$results[
'max_points'];
3450 $found[
"test"][
"total_reached_points"] =
$results[
'reached_points'];
3451 $found[
"test"][
"total_requested_hints"] =
$results[
'hint_count'];
3452 $found[
"test"][
"total_hint_points"] =
$results[
'hint_points'];
3453 $found[
"test"][
"result_pass"] =
$results[
'pass'];
3454 $found[
'test'][
'result_tstamp'] =
$results[
'tstamp'];
3455 $found[
'test'][
'obligations_answered'] =
$results[
'obligations_answered'];
3457 if ((!$found[
'pass'][
'total_reached_points']) or (!$found[
'pass'][
'total_max_points'])) {
3460 $percentage = ($found[
'pass'][
'total_reached_points'] / $found[
'pass'][
'total_max_points']) * 100.0;
3462 if ($percentage < 0) {
3467 $found[
"test"][
"passed"] =
$results[
'passed'];
3483 $result =
$ilDB->queryF(
3484 "SELECT COUNT(active_id) total FROM tst_active WHERE test_fi = %s",
3486 array($this->getTestId())
3488 $row =
$ilDB->fetchAssoc($result);
3489 return $row[
"total"];
3503 $result =
$ilDB->queryF(
3504 "SELECT tst_times.* FROM tst_active, tst_times WHERE tst_active.test_fi = %s AND tst_active.active_id = tst_times.active_fi AND tst_active.user_fi = %s",
3505 array(
'integer',
'integer'),
3506 array($this->getTestId(), $user_id)
3509 while ($row =
$ilDB->fetchAssoc($result)) {
3510 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row[
"started"], $matches);
3511 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
3512 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row[
"finished"], $matches);
3513 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
3514 $time += ($epoch_2 - $epoch_1);
3527 return $this->_getCompleteWorkingTimeOfParticipants($this->getTestId());
3542 $result =
$ilDB->queryF(
3543 "SELECT tst_times.* FROM tst_active, tst_times WHERE tst_active.test_fi = %s AND tst_active.active_id = tst_times.active_fi ORDER BY tst_times.active_fi, tst_times.started",
3549 while ($row =
$ilDB->fetchAssoc($result)) {
3550 if (!array_key_exists($row[
"active_fi"], $times)) {
3551 $times[$row[
"active_fi"]] = 0;
3553 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row[
"started"], $matches);
3554 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
3555 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row[
"finished"], $matches);
3556 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
3557 $times[$row[
"active_fi"]] += ($epoch_2 - $epoch_1);
3573 $result =
$ilDB->queryF(
3574 "SELECT tst_times.* FROM tst_active, tst_times WHERE tst_active.test_fi = %s AND tst_active.active_id = tst_times.active_fi AND tst_active.active_id = %s ORDER BY tst_times.active_fi, tst_times.started",
3575 array(
'integer',
'integer'),
3576 array($this->getTestId(), $active_id)
3579 while ($row =
$ilDB->fetchAssoc($result)) {
3580 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row[
"started"], $matches);
3581 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
3582 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row[
"finished"], $matches);
3583 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
3584 $time += ($epoch_2 - $epoch_1);
3600 $result =
$ilDB->queryF(
3601 "SELECT * FROM tst_times WHERE active_fi = %s AND pass = %s ORDER BY started",
3602 array(
'integer',
'integer'),
3603 array($active_id, $pass)
3606 while ($row =
$ilDB->fetchAssoc($result)) {
3607 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row[
"started"], $matches);
3608 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
3609 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row[
"finished"], $matches);
3610 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
3611 $time += ($epoch_2 - $epoch_1);
3641 $result =
$ilDB->queryF(
3642 "SELECT tst_times.* FROM tst_active, tst_times WHERE tst_active.test_fi = %s AND tst_active.active_id = tst_times.active_fi AND tst_active.active_id = %s ORDER BY tst_times.started",
3643 array(
'integer',
'integer'),
3644 array($test_id, $active_id)
3648 while ($row =
$ilDB->fetchAssoc($result)) {
3649 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row[
"started"], $matches);
3650 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
3651 if ($firstvisit == 0 || $epoch_1 < $firstvisit) {
3652 $firstvisit = $epoch_1;
3654 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row[
"finished"], $matches);
3655 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
3656 if ($epoch_2 > $lastvisit) {
3657 $lastvisit = $epoch_2;
3660 return array(
"firstvisit" => $firstvisit,
"lastvisit" => $lastvisit);
3672 $test_result = &$this->getTestResult($active_id, $pass);
3673 $result =
$ilDB->queryF(
3674 "SELECT tst_times.* FROM tst_active, tst_times WHERE tst_active.active_id = %s AND tst_active.active_id = tst_times.active_fi",
3681 while ($row =
$ilDB->fetchObject($result)) {
3682 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->started, $matches);
3683 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
3684 if (!$first_visit) {
3685 $first_visit = $epoch_1;
3687 if ($epoch_1 < $first_visit) {
3688 $first_visit = $epoch_1;
3690 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->finished, $matches);
3691 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
3693 $last_visit = $epoch_2;
3695 if ($epoch_2 > $last_visit) {
3696 $last_visit = $epoch_2;
3698 $times[$row->active_fi] += ($epoch_2 - $epoch_1);
3701 foreach ($times as
$key => $value) {
3702 $max_time += $value;
3704 if ((!$test_result[
"test"][
"total_reached_points"]) or (!$test_result[
"test"][
"total_max_points"])) {
3707 $percentage = ($test_result[
"test"][
"total_reached_points"] / $test_result[
"test"][
"total_max_points"]) * 100.0;
3708 if ($percentage < 0) {
3712 $mark_obj = $this->mark_schema->getMatchingMark($percentage);
3713 $first_date = getdate($first_visit);
3714 $last_date = getdate($last_visit);
3715 $qworkedthrough = 0;
3716 foreach ($test_result as
$key => $value) {
3717 if (preg_match(
"/\d+/",
$key)) {
3718 $qworkedthrough += $value[
"workedthrough"];
3721 if (!$qworkedthrough) {
3724 $atimeofwork = $max_time / $qworkedthrough;
3727 $obligationsAnswered = $test_result[
"test"][
"obligations_answered"];
3733 $result_mark = $mark_obj->getShortName();
3735 if ($mark_obj->getPassed() && $obligationsAnswered) {
3741 $percent_worked_through = 0;
3742 if (count($this->questions)) {
3743 $percent_worked_through = $qworkedthrough / count($this->questions);
3745 $result_array = array(
3746 "qworkedthrough" => $qworkedthrough,
3747 "qmax" => count($this->questions),
3748 "pworkedthrough" => $percent_worked_through,
3749 "timeofwork" => $max_time,
3750 "atimeofwork" => $atimeofwork,
3751 "firstvisit" => $first_date,
3752 "lastvisit" => $last_date,
3753 "resultspoints" => $test_result[
"test"][
"total_reached_points"],
3754 "maxpoints" => $test_result[
"test"][
"total_max_points"],
3755 "resultsmarks" => $result_mark,
3756 "passed" => $passed,
3757 "distancemedian" =>
"0"
3759 foreach ($test_result as
$key => $value) {
3760 if (preg_match(
"/\d+/",
$key)) {
3761 $result_array[
$key] = $value;
3764 return $result_array;
3776 $totalpoints_array = array();
3777 $all_users = $this->evalTotalParticipantsArray();
3778 foreach ($all_users as $active_id => $user_name) {
3779 $test_result = &$this->getTestResult($active_id);
3780 $reached = $test_result[
"test"][
"total_reached_points"];
3781 $total = $test_result[
"test"][
"total_max_points"];
3782 $percentage = $total != 0 ? $reached / $total : 0;
3783 $mark = $this->mark_schema->getMatchingMark($percentage * 100.0);
3785 $obligationsAnswered = $test_result[
"test"][
"obligations_answered"];
3788 if ($mark->getPassed() && $obligationsAnswered) {
3789 array_push($totalpoints_array, $test_result[
"test"][
"total_reached_points"]);
3793 return $totalpoints_array;
3805 $result =
$ilDB->queryF(
3806 "SELECT tst_active.active_id, usr_data.usr_id, usr_data.firstname, usr_data.lastname, usr_data.title, usr_data.login FROM tst_active LEFT JOIN usr_data ON tst_active.user_fi = usr_data.usr_id WHERE tst_active.test_fi = %s ORDER BY usr_data.lastname ASC",
3808 array($this->getTestId())
3810 $persons_array = array();
3811 while ($row =
$ilDB->fetchAssoc($result)) {
3812 $name = $this->
lng->txt(
"anonymous");
3813 $fullname = $this->
lng->txt(
"anonymous");
3815 if (!$this->getAnonymity()) {
3816 if (strlen($row[
"firstname"] . $row[
"lastname"] . $row[
"title"]) == 0) {
3817 $name = $this->
lng->txt(
"deleted_user");
3818 $fullname = $this->
lng->txt(
"deleted_user");
3819 $login = $this->
lng->txt(
"unknown");
3821 $login = $row[
"login"];
3823 $name = $this->
lng->txt(
"anonymous");
3824 $fullname = $this->
lng->txt(
"anonymous");
3826 $name = trim($row[
"lastname"] .
", " . $row[
"firstname"] .
" " . $row[
"title"]);
3827 $fullname = trim($row[
"title"] .
" " . $row[
"firstname"] .
" " . $row[
"lastname"]);
3831 $persons_array[$row[
"active_id"]] = array(
3833 "fullname" => $fullname,
3837 return $persons_array;
3850 $result =
$ilDB->queryF(
3851 "SELECT tst_active.user_fi, tst_active.active_id, usr_data.firstname, usr_data.lastname, usr_data.title FROM tst_active LEFT JOIN usr_data ON tst_active.user_fi = usr_data.usr_id WHERE tst_active.test_fi = %s ORDER BY usr_data.lastname " . strtoupper($name_sort_order),
3853 array($this->getTestId())
3855 $persons_array = array();
3856 while ($row =
$ilDB->fetchAssoc($result)) {
3857 if ($this->getAccessFilteredParticipantList() && !$this->getAccessFilteredParticipantList()->isActiveIdInList($row[
"active_id"])) {
3861 if ($this->getAnonymity()) {
3862 $persons_array[$row[
"active_id"]] = $this->
lng->txt(
"anonymous");
3864 if (strlen($row[
"firstname"] . $row[
"lastname"] . $row[
"title"]) == 0) {
3865 $persons_array[$row[
"active_id"]] = $this->
lng->txt(
"deleted_user");
3868 $persons_array[$row[
"active_id"]] = $row[
"lastname"];
3870 $persons_array[$row[
"active_id"]] = trim($row[
"lastname"] .
", " . $row[
"firstname"] .
" " . $row[
"title"]);
3875 return $persons_array;
3887 $result =
$ilDB->queryF(
3888 "SELECT tst_active.user_fi, tst_active.active_id, usr_data.login, usr_data.firstname, usr_data.lastname, usr_data.title FROM tst_active LEFT JOIN usr_data ON tst_active.user_fi = usr_data.usr_id WHERE tst_active.test_fi = %s ORDER BY usr_data.lastname " . strtoupper($name_sort_order),
3890 array($this->getTestId())
3892 $persons_array = array();
3893 while ($row =
$ilDB->fetchAssoc($result)) {
3894 if ($this->getAnonymity()) {
3895 $persons_array[$row[
"active_id"]] = array(
"name" => $this->
lng->txt(
"anonymous"));
3897 if (strlen($row[
"firstname"] . $row[
"lastname"] . $row[
"title"]) == 0) {
3898 $persons_array[$row[
"active_id"]] = array(
"name" => $this->
lng->txt(
"deleted_user"));
3901 $persons_array[$row[
"active_id"]] = array(
"name" => $row[
"lastname"]);
3903 $persons_array[$row[
"active_id"]] = array(
"name" => trim($row[
"lastname"] .
", " . $row[
"firstname"] .
" " . $row[
"title"]),
"login" => $row[
"login"]);
3908 return $persons_array;
3921 if ($this->isRandomTest()) {
3922 $ilDB->setLimit($this->getQuestionCount(), 0);
3923 $result =
$ilDB->queryF(
3924 "SELECT tst_test_rnd_qst.sequence, tst_test_rnd_qst.question_fi, " .
3925 "tst_test_rnd_qst.pass, qpl_questions.points " .
3926 "FROM tst_test_rnd_qst, qpl_questions " .
3927 "WHERE tst_test_rnd_qst.question_fi = qpl_questions.question_id " .
3928 "AND tst_test_rnd_qst.active_fi = %s ORDER BY tst_test_rnd_qst.sequence",
3933 $result =
$ilDB->queryF(
3934 "SELECT tst_test_question.sequence, tst_test_question.question_fi, " .
3935 "qpl_questions.points " .
3936 "FROM tst_test_question, tst_active, qpl_questions " .
3937 "WHERE tst_test_question.question_fi = qpl_questions.question_id " .
3938 "AND tst_active.active_id = %s AND tst_active.test_fi = tst_test_question.test_fi",
3944 if ($result->numRows()) {
3945 while ($row =
$ilDB->fetchAssoc($result)) {
3946 array_push($qtest, $row);
3962 if ($this->isRandomTest()) {
3963 $ilDB->setLimit($this->getQuestionCount(), 0);
3964 $result =
$ilDB->queryF(
3965 "SELECT tst_test_rnd_qst.sequence, tst_test_rnd_qst.question_fi, " .
3966 "qpl_questions.points " .
3967 "FROM tst_test_rnd_qst, qpl_questions " .
3968 "WHERE tst_test_rnd_qst.question_fi = qpl_questions.question_id " .
3969 "AND tst_test_rnd_qst.active_fi = %s AND tst_test_rnd_qst.pass = %s " .
3970 "ORDER BY tst_test_rnd_qst.sequence",
3971 array(
'integer',
'integer'),
3972 array($active_id, $pass)
3975 $result =
$ilDB->queryF(
3976 "SELECT tst_test_question.sequence, tst_test_question.question_fi, " .
3977 "qpl_questions.points " .
3978 "FROM tst_test_question, tst_active, qpl_questions " .
3979 "WHERE tst_test_question.question_fi = qpl_questions.question_id " .
3980 "AND tst_active.active_id = %s AND tst_active.test_fi = tst_test_question.test_fi",
3986 if ($result->numRows()) {
3987 while ($row =
$ilDB->fetchAssoc($result)) {
3988 array_push($qpass, $row);
4002 return $this->accessFilteredParticipantList;
4010 $this->accessFilteredParticipantList = $accessFilteredParticipantList;
4019 $list->initializeFromDbRows($this->getTestParticipants());
4021 $list = $list->getAccessFilteredList(
4038 SELECT tst_test_result.*,
4039 qpl_questions.original_id,
4040 qpl_questions.title questiontitle,
4041 qpl_questions.points maxpoints
4043 FROM tst_test_result, qpl_questions, tst_active
4045 WHERE tst_active.active_id = tst_test_result.active_fi
4046 AND qpl_questions.question_id = tst_test_result.question_fi
4047 AND tst_active.test_fi = %s
4049 ORDER BY tst_active.active_id ASC, tst_test_result.pass ASC, tst_test_result.tstamp DESC
4052 $result =
$ilDB->queryF(
4055 array($this->getTestId())
4063 while ($row =
$ilDB->fetchAssoc($result)) {
4064 if (!
$data->participantExists($row[
"active_fi"])) {
4068 $participantObject =
$data->getParticipant($row[
"active_fi"]);
4069 $passObject = $participantObject->getPass($row[
"pass"]);
4075 $passObject->addAnsweredQuestion(
4076 $row[
"question_fi"],
4085 foreach (array_keys(
$data->getParticipants()) as $active_id) {
4086 if ($this->isRandomTest()) {
4087 for ($testpass = 0; $testpass <=
$data->getParticipant($active_id)->getLastPass(); $testpass++) {
4088 $ilDB->setLimit($this->getQuestionCount(), 0);
4091 SELECT tst_test_rnd_qst.sequence, tst_test_rnd_qst.question_fi, qpl_questions.original_id,
4092 tst_test_rnd_qst.pass, qpl_questions.points, qpl_questions.title
4093 FROM tst_test_rnd_qst, qpl_questions
4094 WHERE tst_test_rnd_qst.question_fi = qpl_questions.question_id
4095 AND tst_test_rnd_qst.pass = %s
4096 AND tst_test_rnd_qst.active_fi = %s ORDER BY tst_test_rnd_qst.sequence
4099 $result =
$ilDB->queryF(
4101 array(
'integer',
'integer'),
4102 array($testpass, $active_id)
4105 if ($result->numRows()) {
4106 while ($row =
$ilDB->fetchAssoc($result)) {
4107 $tpass = array_key_exists(
"pass", $row) ? $row[
"pass"] : 0;
4109 $data->getParticipant($active_id)->addQuestion(
4110 $row[
"original_id"],
4111 $row[
"question_fi"],
4117 $data->addQuestionTitle($row[
"question_fi"], $row[
"title"]);
4121 } elseif ($this->isDynamicTest()) {
4122 $lastPass =
$data->getParticipant($active_id)->getLastPass();
4123 for ($testpass = 0; $testpass <= $lastPass; $testpass++) {
4125 $DIC->repositoryTree(),
4127 $DIC[
'component.repository'],
4130 $dynamicQuestionSetConfig->loadFromDb();
4133 $testSequence = $testSequenceFactory->getSequenceByActiveIdAndPass($active_id, $testpass);
4135 $testSequence->loadFromDb($dynamicQuestionSetConfig);
4138 $sequence = $testSequence->getUserSequenceQuestions();
4140 $questionsIdsToRequest = array_diff(array_values($sequence), array_values($questionData));
4141 if (count($questionsIdsToRequest) > 0) {
4142 $questionIdsCondition =
' ' .
$DIC->database()->in(
'question_id', array_values($questionsIdsToRequest),
false,
'integer') .
' ';
4148 WHERE {$questionIdsCondition}",
4152 while ($row =
$DIC->database()->fetchAssoc(
$res)) {
4153 $questionData[$row[
'question_id']] = $row;
4154 $data->addQuestionTitle($row[
'question_id'], $row[
'title']);
4158 foreach ($sequence as $questionId) {
4159 if (!isset($questionData[$questionId])) {
4163 $row = $questionData[$questionId];
4165 $data->getParticipant(
4168 $row[
'original_id'],
4169 $row[
'question_id'],
4178 SELECT tst_test_question.sequence, tst_test_question.question_fi,
4179 qpl_questions.points, qpl_questions.title, qpl_questions.original_id
4180 FROM tst_test_question, tst_active, qpl_questions
4181 WHERE tst_test_question.question_fi = qpl_questions.question_id
4182 AND tst_active.active_id = %s
4183 AND tst_active.test_fi = tst_test_question.test_fi
4184 ORDER BY tst_test_question.sequence
4187 $result =
$ilDB->queryF(
4193 if ($result->numRows()) {
4194 $questionsbysequence = array();
4196 while ($row =
$ilDB->fetchAssoc($result)) {
4197 $questionsbysequence[$row[
"sequence"]] = $row;
4200 $seqresult =
$ilDB->queryF(
4201 "SELECT * FROM tst_sequence WHERE active_fi = %s",
4206 while ($seqrow =
$ilDB->fetchAssoc($seqresult)) {
4207 $questionsequence = unserialize($seqrow[
"sequence"]);
4209 foreach ($questionsequence as $sidx => $seq) {
4210 $data->getParticipant($active_id)->addQuestion(
4211 $questionsbysequence[$seq][
"original_id"],
4212 $questionsbysequence[$seq][
"question_fi"],
4213 $questionsbysequence[$seq][
"points"],
4218 $data->addQuestionTitle(
4219 $questionsbysequence[$seq][
"question_fi"],
4220 $questionsbysequence[$seq][
"title"]
4228 if ($this->getECTSOutput()) {
4229 $passed_array = &$this->getTotalPointsPassedArray();
4232 foreach (array_keys(
$data->getParticipants()) as $active_id) {
4233 $tstUserData =
$data->getParticipant($active_id);
4235 $percentage = $tstUserData->getReachedPointsInPercent();
4237 $obligationsAnswered = $tstUserData->areObligationsAnswered();
4239 $mark = $this->mark_schema->getMatchingMark($percentage);
4241 if (is_object($mark)) {
4242 $tstUserData->setMark($mark->getShortName());
4243 $tstUserData->setMarkOfficial($mark->getOfficialName());
4245 $tstUserData->setPassed(
4246 $mark->getPassed() && $tstUserData->areObligationsAnswered()
4250 if ($this->getECTSOutput()) {
4251 $ects_mark = $this->getECTSGrade(
4253 $tstUserData->getReached(),
4254 $tstUserData->getMaxPoints()
4257 $tstUserData->setECTSMark($ects_mark);
4260 $visitingTime = $this->getVisitTimeOfParticipant($active_id);
4262 $tstUserData->setFirstVisit($visitingTime[
"firstvisit"]);
4263 $tstUserData->setLastVisit($visitingTime[
"lastvisit"]);
4276 switch ($questionSetType) {
4281 SELECT COUNT(qpl_questions.question_id) qcount,
4282 SUM(qpl_questions.points) qsum
4284 INNER JOIN tst_tests
4285 ON tst_tests.test_id = tst_active.test_fi
4286 INNER JOIN tst_dyn_quest_set_cfg
4287 ON tst_dyn_quest_set_cfg.test_fi = tst_tests.test_id
4288 INNER JOIN qpl_questions
4289 ON qpl_questions.obj_fi = tst_dyn_quest_set_cfg.source_qpl_fi
4290 AND qpl_questions.original_id IS NULL
4291 AND qpl_questions.complete = %s
4292 WHERE tst_active.active_id = %s
4294 array(
'integer',
'integer'),
4295 array(1, $active_id)
4304 SELECT tst_test_rnd_qst.pass,
4305 COUNT(tst_test_rnd_qst.question_fi) qcount,
4306 SUM(qpl_questions.points) qsum
4308 FROM tst_test_rnd_qst,
4311 WHERE tst_test_rnd_qst.question_fi = qpl_questions.question_id
4312 AND tst_test_rnd_qst.active_fi = %s
4315 GROUP BY tst_test_rnd_qst.active_fi,
4316 tst_test_rnd_qst.pass
4318 array(
'integer',
'integer'),
4319 array($active_id, $pass)
4328 SELECT COUNT(tst_test_question.question_fi) qcount,
4329 SUM(qpl_questions.points) qsum
4331 FROM tst_test_question,
4335 WHERE tst_test_question.question_fi = qpl_questions.question_id
4336 AND tst_test_question.test_fi = tst_active.test_fi
4337 AND tst_active.active_id = %s
4339 GROUP BY tst_test_question.test_fi
4349 throw new ilTestException(
"not supported question set type: $questionSetType");
4354 if (is_array($row)) {
4355 return array(
"count" => $row[
"qcount"],
"points" => $row[
"qsum"]);
4358 return array(
"count" => 0,
"points" => 0);
4363 $data = $this->getUnfilteredEvaluationData();
4364 if ($withStatistics) {
4365 $data->calculateStatistics();
4367 $data->setFilter($filterby, $filtertext);
4379 return $this->_evalResultsOverview($this->getTestId());
4393 $result =
$ilDB->queryF(
4394 "SELECT usr_data.usr_id, usr_data.firstname, usr_data.lastname, usr_data.title, usr_data.login, " .
4395 "tst_test_result.*, qpl_questions.original_id, qpl_questions.title questiontitle, " .
4396 "qpl_questions.points maxpoints " .
4397 "FROM tst_test_result, qpl_questions, tst_active " .
4398 "LEFT JOIN usr_data ON tst_active.user_fi = usr_data.usr_id " .
4399 "WHERE tst_active.active_id = tst_test_result.active_fi " .
4400 "AND qpl_questions.question_id = tst_test_result.question_fi " .
4401 "AND tst_active.test_fi = %s " .
4402 "ORDER BY tst_active.active_id, tst_test_result.pass, tst_test_result.tstamp",
4406 $overview = array();
4407 while ($row =
$ilDB->fetchAssoc($result)) {
4408 if (!array_key_exists($row[
"active_fi"], $overview)) {
4409 $overview[$row[
"active_fi"]] = array();
4410 $overview[$row[
"active_fi"]][
"firstname"] = $row[
"firstname"];
4411 $overview[$row[
"active_fi"]][
"lastname"] = $row[
"lastname"];
4412 $overview[$row[
"active_fi"]][
"title"] = $row[
"title"];
4413 $overview[$row[
"active_fi"]][
"login"] = $row[
"login"];
4414 $overview[$row[
"active_fi"]][
"usr_id"] = $row[
"usr_id"];
4415 $overview[$row[
"active_fi"]][
"started"] = $row[
"started"];
4416 $overview[$row[
"active_fi"]][
"finished"] = $row[
"finished"];
4418 if (!array_key_exists($row[
"pass"], $overview[$row[
"active_fi"]])) {
4419 $overview[$row[
"active_fi"]][$row[
"pass"]] = array();
4420 $overview[$row[
"active_fi"]][$row[
"pass"]][
"reached"] = 0;
4421 $overview[$row[
"active_fi"]][$row[
"pass"]][
"maxpoints"] = $row[
"maxpoints"];
4423 array_push($overview[$row[
"active_fi"]][$row[
"pass"]], $row);
4424 $overview[$row[
"active_fi"]][$row[
"pass"]][
"reached"] += $row[
"points"];
4441 $result =
$ilDB->queryF(
4442 "SELECT usr_data.usr_id, usr_data.firstname, usr_data.lastname, usr_data.title, usr_data.login, " .
4443 "tst_test_result.*, qpl_questions.original_id, qpl_questions.title questiontitle, " .
4444 "qpl_questions.points maxpoints " .
4445 "FROM tst_test_result, qpl_questions, tst_active " .
4446 "LEFT JOIN usr_data ON tst_active.user_fi = usr_data.usr_id " .
4447 "WHERE tst_active.active_id = tst_test_result.active_fi " .
4448 "AND qpl_questions.question_id = tst_test_result.question_fi " .
4449 "AND tst_active.test_fi = %s AND tst_active.active_id = %s" .
4450 "ORDER BY tst_active.active_id, tst_test_result.pass, tst_test_result.tstamp",
4451 array(
'integer',
'integer'),
4452 array($this->getTestId(), $active_id)
4454 $overview = array();
4455 while ($row =
$ilDB->fetchAssoc($result)) {
4456 if (!array_key_exists($row[
"active_fi"], $overview)) {
4457 $overview[$row[
"active_fi"]] = array();
4458 $overview[$row[
"active_fi"]][
"firstname"] = $row[
"firstname"];
4459 $overview[$row[
"active_fi"]][
"lastname"] = $row[
"lastname"];
4460 $overview[$row[
"active_fi"]][
"title"] = $row[
"title"];
4461 $overview[$row[
"active_fi"]][
"login"] = $row[
"login"];
4462 $overview[$row[
"active_fi"]][
"usr_id"] = $row[
"usr_id"];
4463 $overview[$row[
"active_fi"]][
"started"] = $row[
"started"];
4464 $overview[$row[
"active_fi"]][
"finished"] = $row[
"finished"];
4466 if (!array_key_exists($row[
"pass"], $overview[$row[
"active_fi"]])) {
4467 $overview[$row[
"active_fi"]][$row[
"pass"]] = array();
4468 $overview[$row[
"active_fi"]][$row[
"pass"]][
"reached"] = 0;
4469 $overview[$row[
"active_fi"]][$row[
"pass"]][
"maxpoints"] = $row[
"maxpoints"];
4471 array_push($overview[$row[
"active_fi"]][$row[
"pass"]], $row);
4472 $overview[$row[
"active_fi"]][$row[
"pass"]][
"reached"] += $row[
"points"];
4488 public function buildName($user_id, $firstname, $lastname, $title): string
4491 if (strlen($firstname . $lastname . $title) == 0) {
4492 $name = $this->
lng->txt(
"deleted_user");
4497 $name = trim($lastname .
", " . $firstname .
" " . $title);
4499 if ($this->getAnonymity()) {
4500 $name = $this->
lng->txt(
"anonymous");
4518 public function _buildName($is_anonymous, $user_id, $firstname, $lastname, $title): string
4523 if (strlen($firstname . $lastname . $title) == 0) {
4529 $name = trim($lastname .
", " . $firstname .
" " . $title);
4531 if ($is_anonymous) {
4548 $query =
"SELECT tst_times.* FROM tst_active, tst_times WHERE tst_active.test_fi = %s AND tst_active.active_id = tst_times.active_fi";
4550 if (is_array($activeIdsFilter) && count($activeIdsFilter)) {
4551 $query .=
" AND " .
$DIC->database()->in(
'active_id', $activeIdsFilter,
false,
'integer');
4554 $result =
$DIC->database()->queryF(
$query, array(
'integer'), array($this->getTestId()));
4556 while ($row =
$DIC->database()->fetchObject($result)) {
4557 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->started, $matches);
4558 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
4559 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->finished, $matches);
4560 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
4561 if (isset($times[$row->active_fi])) {
4562 $times[$row->active_fi] += ($epoch_2 - $epoch_1);
4564 $times[$row->active_fi] = ($epoch_2 - $epoch_1);
4569 foreach ($times as
$key => $value) {
4570 $max_time += $value;
4574 $average_time = round($max_time / $counter);
4578 return $average_time;
4587 public function getAvailableQuestionpools($use_object_id =
false, $equal_points =
false, $could_be_offline =
false, $show_path =
false, $with_questioncount =
false, $permission =
"read"): array
4600 $time_in_seconds = 0;
4601 foreach ($this->questions as $question_id) {
4603 $est_time = $question->getEstimatedWorkingTime();
4604 $time_in_seconds += $est_time[
"h"] * 3600 + $est_time[
"m"] * 60 + $est_time[
"s"];
4606 $hours = (
int) ($time_in_seconds / 3600) ;
4607 $time_in_seconds = $time_in_seconds - ($hours * 3600);
4608 $minutes = (
int) ($time_in_seconds / 60);
4609 $time_in_seconds = $time_in_seconds - ($minutes * 60);
4610 $result = array(
"hh" => $hours,
"mm" => $minutes,
"ss" => $time_in_seconds);
4651 if ((!$question_type) and ($question_id > 0)) {
4652 $question_type = $this->getQuestionType($question_id);
4655 if (!strlen($question_type)) {
4661 $question_type_gui = $question_type .
'GUI';
4662 $question =
new $question_type_gui();
4664 if ($question_id > 0) {
4665 $question->object->loadFromDb($question_id);
4668 $ilCtrl =
$DIC[
'ilCtrl'];
4674 $question->object->feedbackOBJ =
new $feedbackObjectClassname($question->object, $ilCtrl,
$ilDB,
$lng);
4676 $assSettings =
new ilSetting(
'assessment');
4678 $processLockerFactory->setQuestionId($question->object->getId());
4679 $processLockerFactory->setUserId(
$ilUser->getId());
4681 $question->object->setProcessLocker($processLockerFactory->getLocker());
4695 if (strcmp((
string) $question_id,
"") !== 0) {
4712 $this->questions = array_values($this->questions);
4713 $array_pos = array_search($target_index, $this->questions);
4714 if ($insert_mode == 0) {
4715 $part1 = array_slice($this->questions, 0, $array_pos);
4716 $part2 = array_slice($this->questions, $array_pos);
4717 } elseif ($insert_mode == 1) {
4718 $part1 = array_slice($this->questions, 0, $array_pos + 1);
4719 $part2 = array_slice($this->questions, $array_pos + 1);
4721 foreach ($move_questions as $question_id) {
4722 if (!(array_search($question_id, $part1) ===
false)) {
4723 unset($part1[array_search($question_id, $part1)]);
4725 if (!(array_search($question_id, $part2) ===
false)) {
4726 unset($part2[array_search($question_id, $part2)]);
4729 $part1 = array_values($part1);
4730 $part2 = array_values($part2);
4731 $new_array = array_values(array_merge($part1, $move_questions, $part2));
4732 $this->questions = array();
4734 foreach ($new_array as $question_id) {
4735 $this->questions[$counter] = $question_id;
4738 $this->saveQuestionsToDb();
4751 if ($this->isStartingTimeEnabled() && $this->getStartingTime() != 0) {
4753 if ($now < $this->getStartingTime()) {
4769 if ($this->isEndingTimeEnabled() && $this->getEndingTime() != 0) {
4771 if ($now > $this->getEndingTime()) {
4786 $component_repository =
$DIC[
'component.repository'];
4787 $component_factory =
$DIC[
'component.factory'];
4794 if (count($available_pools)) {
4795 $available =
" AND " .
$ilDB->in(
'qpl_questions.obj_fi', $available_pools,
false,
'integer');
4799 if ($completeonly) {
4800 $available .=
" AND qpl_questions.complete = " .
$ilDB->quote(
"1",
'text');
4804 if (is_array($arrFilter)) {
4805 if (array_key_exists(
'title', $arrFilter) && strlen($arrFilter[
'title'])) {
4806 $where .=
" AND " .
$ilDB->like(
'qpl_questions.title',
'text',
"%%" . $arrFilter[
'title'] .
"%%");
4808 if (array_key_exists(
'description', $arrFilter) && strlen($arrFilter[
'description'])) {
4809 $where .=
" AND " .
$ilDB->like(
'qpl_questions.description',
'text',
"%%" . $arrFilter[
'description'] .
"%%");
4811 if (array_key_exists(
'author', $arrFilter) && strlen($arrFilter[
'author'])) {
4812 $where .=
" AND " .
$ilDB->like(
'qpl_questions.author',
'text',
"%%" . $arrFilter[
'author'] .
"%%");
4814 if (array_key_exists(
'type', $arrFilter) && strlen($arrFilter[
'type'])) {
4815 $where .=
" AND qpl_qst_type.type_tag = " .
$ilDB->quote($arrFilter[
'type'],
'text');
4817 if (array_key_exists(
'qpl', $arrFilter) && strlen($arrFilter[
'qpl'])) {
4818 $where .=
" AND " .
$ilDB->like(
'object_data.title',
'text',
"%%" . $arrFilter[
'qpl'] .
"%%");
4822 $original_ids = &$this->getExistingQuestions();
4823 $original_clause =
" qpl_questions.original_id IS NULL";
4824 if (count($original_ids)) {
4825 $original_clause =
" qpl_questions.original_id IS NULL AND " .
$ilDB->in(
'qpl_questions.question_id', $original_ids,
true,
'integer');
4828 $query_result =
$ilDB->query(
"
4829 SELECT qpl_questions.*, qpl_questions.tstamp,
4830 qpl_qst_type.type_tag, qpl_qst_type.plugin, qpl_qst_type.plugin_name,
4831 object_data.title parent_title
4832 FROM qpl_questions, qpl_qst_type, object_data
4833 WHERE $original_clause $available
4834 AND object_data.obj_id = qpl_questions.obj_fi
4835 AND qpl_questions.tstamp > 0
4836 AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id
4841 if ($query_result->numRows()) {
4842 while ($row =
$ilDB->fetchAssoc($query_result)) {
4845 if (!$row[
'plugin']) {
4846 $row[
'ttype' ] =
$lng->txt($row[
"type_tag" ]);
4852 $plugin = $component_repository->getPluginByName($row[
'plugin_name']);
4857 $pl = $component_factory->getPlugin(
$plugin->getId());
4858 $row[
'ttype' ] = $pl->getQuestionTypeTranslation();
4874 $this->setDescription($assessment->
getComment());
4875 $this->setTitle($assessment->
getTitle());
4877 $this->setIntroductionEnabled(
false);
4878 foreach ($assessment->objectives as
$objectives) {
4880 $intro = $this->QTIMaterialToString($material);
4881 $this->setIntroduction($intro);
4882 $this->setIntroductionEnabled(strlen($intro) > 0);
4891 $this->setFinalStatement($this->QTIMaterialToString($assessment->
getPresentationMaterial()->getFlowMat(0)->getMaterial(0)));
4894 foreach ($assessment->assessmentcontrol as $assessmentcontrol) {
4895 switch ($assessmentcontrol->getSolutionswitch()) {
4897 $this->setInstantFeedbackSolution(1);
4900 $this->setInstantFeedbackSolution(0);
4905 $this->setStartingTimeEnabled(
false);
4906 $this->setEndingTimeEnabled(
false);
4907 $this->setPasswordEnabled(
false);
4908 $this->setLimitUsersEnabled(
false);
4911 $score_settings = $this->getScoreSettings();
4916 foreach ($assessment->qtimetadata as $metadata) {
4917 switch ($metadata[
"label"]) {
4920 $type = $metadata[
"entry"];
4924 $this->setAnonymity(1);
4931 $this->setFixedParticipants(1);
4932 $this->setListOfQuestionsSettings(7);
4939 case "sequence_settings":
4940 $this->setSequenceSettings((
int) $metadata[
"entry"]);
4942 case "solution_details":
4943 $result_details_settings = $result_details_settings->withShowSolutionDetails((
bool) $metadata[
"entry"]);
4945 case "print_bs_with_res":
4946 $result_details_settings = $result_details_settings->withPrintBestSolutionWithResult((
bool) $metadata[
"entry"]);
4949 $this->setAuthor($metadata[
"entry"]);
4952 $this->setNrOfTries($metadata[
"entry"]);
4954 case 'block_after_passed':
4955 $this->setBlockPassesAfterPassedEnabled((
bool) $metadata[
'entry']);
4957 case "pass_waiting":
4958 $this->setPassWaiting($metadata[
"entry"]);
4961 $this->setKiosk($metadata[
"entry"]);
4963 case "showfinalstatement":
4964 $this->setShowFinalStatement($metadata[
"entry"]);
4967 $this->setShowInfo($metadata[
"entry"]);
4970 $this->setForceJS($metadata[
"entry"]);
4973 $this->setCustomStyle($metadata[
"entry"]);
4976 case "highscore_enabled":
4977 $gamification_settings = $gamification_settings->withHighscoreEnabled((
bool) $metadata[
"entry"]);
4980 case "highscore_anon":
4981 $gamification_settings = $gamification_settings->withHighscoreAnon((
bool) $metadata[
"entry"]);
4984 case "highscore_achieved_ts":
4985 $gamification_settings = $gamification_settings->withHighscoreAchievedTS((
bool) $metadata[
"entry"]);
4988 case "highscore_score":
4989 $gamification_settings = $gamification_settings->withHighscoreScore((
bool) $metadata[
"entry"]);
4992 case "highscore_percentage":
4993 $gamification_settings = $gamification_settings->withHighscorePercentage((
bool) $metadata[
"entry"]);
4996 case "highscore_hints":
4997 $gamification_settings = $gamification_settings->withHighscoreHints((
bool) $metadata[
"entry"]);
5000 case "highscore_wtime":
5001 $gamification_settings = $gamification_settings->withHighscoreWTime((
bool) $metadata[
"entry"]);
5004 case "highscore_own_table":
5005 $gamification_settings = $gamification_settings->withHighscoreOwnTable((
bool) $metadata[
"entry"]);
5008 case "highscore_top_table":
5009 $gamification_settings = $gamification_settings->withHighscoreTopTable((
bool) $metadata[
"entry"]);
5012 case "highscore_top_num":
5013 $gamification_settings = $gamification_settings->withHighscoreTopNum((
int) $metadata[
"entry"]);
5016 case "hide_previous_results":
5017 if ($metadata[
"entry"] == 0) {
5018 $this->setUsePreviousAnswers(1);
5020 $this->setUsePreviousAnswers(0);
5023 case "use_previous_answers":
5024 $this->setUsePreviousAnswers($metadata[
"entry"]);
5026 case "answer_feedback":
5027 $this->setAnswerFeedback($metadata[
"entry"]);
5029 case "title_output":
5030 case "hide_title_points":
5031 $this->setTitleOutput($metadata[
"entry"]);
5033 case "question_set_type":
5034 $this->setQuestionSetType($metadata[
"entry"]);
5037 if ($metadata[
"entry"]) {
5038 $this->setQuestionSetType(self::QUESTION_SET_TYPE_RANDOM);
5040 $this->setQuestionSetType(self::QUESTION_SET_TYPE_FIXED);
5043 case "results_presentation":
5044 $result_details_settings = $result_details_settings->withResultsPresentation((
int) $metadata[
"entry"]);
5046 case "reset_processing_time":
5047 $this->setResetProcessingTime($metadata[
"entry"]);
5049 case "instant_verification":
5050 $this->setInstantFeedbackSolution($metadata[
"entry"]);
5052 case "follow_qst_answer_fixation":
5053 $this->setFollowupQuestionAnswerFixationEnabled((
bool) $metadata[
"entry"]);
5055 case "instant_feedback_answer_fixation":
5056 $this->setInstantFeedbackAnswerFixationEnabled((
bool) $metadata[
"entry"]);
5058 case "force_instant_feedback":
5059 $this->setForceInstantFeedbackEnabled((
bool) $metadata[
"entry"]);
5061 case "answer_feedback_points":
5062 $this->setAnswerFeedbackPoints($metadata[
"entry"]);
5065 $this->setAnonymity($metadata[
"entry"]);
5068 $this->setShowCancel($metadata[
"entry"]);
5071 $this->setShowMarker($metadata[
"entry"]);
5073 case "fixed_participants":
5074 $this->setFixedParticipants($metadata[
"entry"]);
5076 case "score_reporting":
5077 $result_summary_settings = $result_summary_settings->withScoreReporting((
int) $metadata[
"entry"]);
5079 case "shuffle_questions":
5080 $this->setShuffleQuestions($metadata[
"entry"]);
5082 case "count_system":
5083 $scoring_settings = $scoring_settings->withCountSystem((
int) $metadata[
"entry"]);
5085 case "mailnotification":
5086 $this->setMailNotification($metadata[
"entry"]);
5089 $this->setMailNotificationType($metadata[
"entry"]);
5091 case "exportsettings":
5092 $result_details_settings = $result_details_settings->withExportSettings((
int) $metadata[
"entry"]);
5094 case "score_cutting":
5095 $scoring_settings = $scoring_settings->withScoreCutting((
int) $metadata[
"entry"]);
5098 $this->setPassword($metadata[
"entry"]);
5099 $this->setPasswordEnabled(strlen($metadata[
"entry"]) > 0);
5101 case "allowedUsers":
5102 $this->setAllowedUsers($metadata[
"entry"]);
5103 $this->setLimitUsersEnabled((
int) $metadata[
"entry"] > 0);
5105 case "allowedUsersTimeGap":
5106 $this->setAllowedUsersTimeGap($metadata[
"entry"]);
5108 case "pass_scoring":
5109 $scoring_settings = $scoring_settings->withPassScoring((
int) $metadata[
"entry"]);
5111 case 'pass_deletion_allowed':
5112 $result_summary_settings = $result_summary_settings->withPassDeletionAllowed((
bool) $metadata[
"entry"]);
5114 case "show_summary":
5115 $this->setListOfQuestionsSettings($metadata[
"entry"]);
5117 case "reporting_date":
5118 $iso8601period = $metadata[
"entry"];
5119 if (preg_match(
"/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches)) {
5120 $this->setReportingDate(sprintf(
"%02d%02d%02d%02d%02d%02d", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]));
5123 case 'enable_processing_time':
5124 $this->setEnableProcessingTime($metadata[
'entry']);
5126 case "processing_time":
5127 $this->setProcessingTime($metadata[
'entry']);
5129 case "starting_time":
5130 $iso8601period = $metadata[
"entry"];
5131 if (preg_match(
"/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches)) {
5132 $date_time =
new ilDateTime(sprintf(
"%02d-%02d-%02d %02d:%02d:%02d", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]),
IL_CAL_DATETIME);
5133 $this->setStartingTime($date_time->get(
IL_CAL_UNIX));
5134 $this->setStartingTimeEnabled(
true);
5138 $iso8601period = $metadata[
"entry"];
5139 if (preg_match(
"/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches)) {
5140 $date_time =
new ilDateTime(sprintf(
"%02d-%02d-%02d %02d:%02d:%02d", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]),
IL_CAL_DATETIME);
5141 $this->setEndingTime($date_time->get(
IL_CAL_UNIX));
5142 $this->setEndingTimeEnabled(
true);
5145 case "enable_examview":
5146 $this->setEnableExamview($metadata[
"entry"]);
5148 case 'show_examview_html':
5149 $this->setShowExamviewHtml($metadata[
'entry']);
5151 case 'show_examview_pdf':
5152 $this->setShowExamviewPdf($metadata[
'entry']);
5154 case 'redirection_mode':
5155 $this->setRedirectionMode($metadata[
'entry']);
5157 case 'redirection_url':
5158 $this->setRedirectionUrl($metadata[
'entry']);
5160 case 'examid_in_kiosk':
5161 case 'examid_in_test_pass':
5162 $this->setShowExamIdInTestPassEnabled($metadata[
'entry']);
5164 case 'show_exam_id':
5165 case 'examid_in_test_res':
5166 $result_details_settings = $result_details_settings->withShowExamIdInTestResults((
bool) $metadata[
"entry"]);
5168 case 'enable_archiving':
5169 $this->setEnableArchiving($metadata[
'entry']);
5171 case 'sign_submission':
5172 $this->setSignSubmission($metadata[
'entry']);
5174 case 'char_selector_availability':
5175 $this->setCharSelectorAvailability($metadata[
'entry']);
5177 case 'char_selector_definition':
5178 $this->setCharSelectorDefinition($metadata[
'entry']);
5180 case 'skill_service':
5181 $this->setSkillServiceEnabled((
bool) $metadata[
'entry']);
5183 case 'result_tax_filters':
5184 $tax_ids = strlen($metadata[
'entry']) ? unserialize($metadata[
'entry']) : [];
5185 $result_details_settings = $result_details_settings->withTaxonomyFilterIds($tax_ids);
5187 case 'show_grading_status':
5188 $result_summary_settings = $result_summary_settings->withShowGradingStatusEnabled((
bool) $metadata[
"entry"]);
5190 case 'show_grading_mark':
5191 $result_summary_settings = $result_summary_settings->withShowGradingMarkEnabled((
bool) $metadata[
"entry"]);
5193 case 'activation_limited':
5194 $this->setActivationLimited($metadata[
'entry']);
5196 case 'activation_start_time':
5197 $this->setActivationStartingTime($metadata[
'entry']);
5199 case 'activation_end_time':
5200 $this->setActivationEndingTime($metadata[
'entry']);
5202 case 'activation_visibility':
5203 $this->setActivationVisibility($metadata[
'entry']);
5206 $this->setAutosave($metadata[
'entry']);
5208 case 'autosave_ival':
5209 $this->setAutosaveIval($metadata[
'entry']);
5211 case 'offer_question_hints':
5212 $this->setOfferingQuestionHintsEnabled($metadata[
'entry']);
5214 case 'instant_feedback_specific':
5215 $this->setSpecificAnswerFeedback($metadata[
'entry']);
5217 case 'obligations_enabled':
5218 $this->setObligationsEnabled($metadata[
'entry']);
5221 if (preg_match(
"/mark_step_\d+/", $metadata[
"label"])) {
5222 $xmlmark = $metadata[
"entry"];
5223 preg_match(
"/<short>(.*?)<\/short>/", $xmlmark, $matches);
5224 $mark_short = $matches[1];
5225 preg_match(
"/<official>(.*?)<\/official>/", $xmlmark, $matches);
5226 $mark_official = $matches[1];
5227 preg_match(
"/<percentage>(.*?)<\/percentage>/", $xmlmark, $matches);
5228 $mark_percentage = $matches[1];
5229 preg_match(
"/<passed>(.*?)<\/passed>/", $xmlmark, $matches);
5230 $mark_passed = $matches[1];
5231 $this->mark_schema->addMarkStep($mark_short, $mark_official, $mark_percentage, $mark_passed);
5236 $result_summary_settings = $result_summary_settings->withShowPassDetails($result_details_settings->getShowPassDetails());
5237 $score_settings = $score_settings
5239 ->withScoringSettings($scoring_settings)
5240 ->withResultDetailsSettings($result_details_settings)
5241 ->withResultSummarySettings($result_summary_settings);
5242 $this->getScoreSettingsRepository()->store($score_settings);
5243 $this->score_settings = $score_settings;
5244 $this->loadFromDb();
5250 if (file_exists($importfile)) {
5257 $ilLog =
$DIC[
'ilLog'];
5258 $ilLog->write(
"Error: Could not open XHTML mob file for test introduction during test import. File $importfile does not exist!");
5274 $a_xml_writer->xmlHeader();
5275 $a_xml_writer->xmlSetDtdDef(
"<!DOCTYPE questestinterop SYSTEM \"ims_qtiasiv1p2p1.dtd\">");
5276 $a_xml_writer->xmlStartTag(
"questestinterop");
5279 "ident" =>
"il_" .
IL_INST_ID .
"_tst_" . $this->getTestId(),
5280 "title" => $this->getTitle()
5282 $a_xml_writer->xmlStartTag(
"assessment", $attrs);
5284 $a_xml_writer->xmlElement(
"qticomment",
null, $this->getDescription());
5287 if ($this->enable_processing_time) {
5288 preg_match(
"/(\d+):(\d+):(\d+)/", $this->processing_time, $matches);
5289 $a_xml_writer->xmlElement(
"duration",
null, sprintf(
"P0Y0M0DT%dH%dM%dS", $matches[1], $matches[2], $matches[3]));
5293 $a_xml_writer->xmlStartTag(
"qtimetadata");
5294 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5295 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"ILIAS_VERSION");
5296 $a_xml_writer->xmlElement(
"fieldentry",
null,
ILIAS_VERSION);
5297 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5300 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5301 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"anonymity");
5302 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getAnonymity()));
5303 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5306 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5307 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"question_set_type");
5308 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getQuestionSetType());
5309 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5312 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5313 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"sequence_settings");
5314 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getSequenceSettings());
5315 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5318 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5319 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"author");
5320 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getAuthor());
5321 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5324 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5325 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"reset_processing_time");
5326 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getResetProcessingTime());
5327 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5330 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5331 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"count_system");
5332 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getCountSystem());
5333 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5336 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5337 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"score_cutting");
5338 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getScoreCutting());
5339 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5342 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5343 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"password");
5344 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getPassword());
5345 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5348 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5349 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"allowedUsers");
5350 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getAllowedUsers());
5351 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5354 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5355 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"allowedUsersTimeGap");
5356 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getAllowedUsersTimeGap());
5357 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5360 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5361 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"pass_scoring");
5362 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getPassScoring());
5363 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5365 $a_xml_writer->xmlStartTag(
'qtimetadatafield');
5366 $a_xml_writer->xmlElement(
'fieldlabel',
null,
'pass_deletion_allowed');
5367 $a_xml_writer->xmlElement(
'fieldentry',
null, (
int) $this->isPassDeletionAllowed());
5368 $a_xml_writer->xmlEndTag(
'qtimetadatafield');
5371 if ($this->getReportingDate()) {
5372 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5373 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"reporting_date");
5374 preg_match(
"/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->reporting_date, $matches);
5375 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"P%dY%dM%dDT%dH%dM%dS", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]));
5376 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5379 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5380 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"nr_of_tries");
5381 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getNrOfTries()));
5382 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5385 $a_xml_writer->xmlStartTag(
'qtimetadatafield');
5386 $a_xml_writer->xmlElement(
'fieldlabel',
null,
'block_after_passed');
5387 $a_xml_writer->xmlElement(
'fieldentry',
null, (
int) $this->isBlockPassesAfterPassedEnabled());
5388 $a_xml_writer->xmlEndTag(
'qtimetadatafield');
5391 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5392 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"pass_waiting");
5393 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getPassWaiting());
5394 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5397 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5398 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"kiosk");
5399 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getKiosk()));
5400 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5404 $a_xml_writer->xmlStartTag(
'qtimetadatafield');
5405 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"redirection_mode");
5406 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getRedirectionMode());
5407 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5410 $a_xml_writer->xmlStartTag(
'qtimetadatafield');
5411 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"redirection_url");
5412 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getRedirectionUrl());
5413 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5416 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5417 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"use_previous_answers");
5418 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getUsePreviousAnswers());
5419 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5422 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5423 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"title_output");
5424 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getTitleOutput()));
5425 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5428 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5429 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"results_presentation");
5430 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getResultsPresentation()));
5431 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5434 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5435 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"examid_in_test_pass");
5436 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->isShowExamIdInTestPassEnabled()));
5437 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5440 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5441 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"examid_in_test_res");
5442 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->isShowExamIdInTestResultsEnabled()));
5443 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5446 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5447 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"show_summary");
5448 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getListOfQuestionsSettings()));
5449 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5452 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5453 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"score_reporting");
5454 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getScoreReporting()));
5455 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5457 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5458 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"solution_details");
5459 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->getShowSolutionDetails());
5460 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5461 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5462 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"print_bs_with_res");
5463 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->getShowSolutionDetails() ? (
int) $this->isBestSolutionPrintedWithResult() : 0);
5464 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5467 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5468 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"instant_verification");
5469 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getInstantFeedbackSolution()));
5470 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5473 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5474 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"answer_feedback");
5475 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getAnswerFeedback()));
5476 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5479 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5480 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"answer_feedback_points");
5481 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getAnswerFeedbackPoints()));
5482 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5485 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5486 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"follow_qst_answer_fixation");
5487 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->isFollowupQuestionAnswerFixationEnabled());
5488 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5491 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5492 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"instant_feedback_answer_fixation");
5493 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->isInstantFeedbackAnswerFixationEnabled());
5494 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5497 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5498 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"force_instant_feedback");
5499 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->isForceInstantFeedbackEnabled());
5500 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5504 $highscore_metadata = array(
5505 'highscore_enabled' => array(
'value' => $this->getHighscoreEnabled()),
5506 'highscore_anon' => array(
'value' => $this->getHighscoreAnon()),
5507 'highscore_achieved_ts' => array(
'value' => $this->getHighscoreAchievedTS()),
5508 'highscore_score' => array(
'value' => $this->getHighscoreScore()),
5509 'highscore_percentage' => array(
'value' => $this->getHighscorePercentage()),
5510 'highscore_hints' => array(
'value' => $this->getHighscoreHints()),
5511 'highscore_wtime' => array(
'value' => $this->getHighscoreWTime()),
5512 'highscore_own_table' => array(
'value' => $this->getHighscoreOwnTable()),
5513 'highscore_top_table' => array(
'value' => $this->getHighscoreTopTable()),
5514 'highscore_top_num' => array(
'value' => $this->getHighscoreTopNum()),
5516 foreach ($highscore_metadata as $label =>
$data) {
5517 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5518 $a_xml_writer->xmlElement(
"fieldlabel",
null, $label);
5519 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d",
$data[
'value']));
5520 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5524 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5525 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"show_cancel");
5526 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getShowCancel()));
5527 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5530 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5531 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"show_marker");
5532 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getShowMarker()));
5533 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5536 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5537 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"fixed_participants");
5538 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getFixedParticipants()));
5539 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5542 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5543 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"showfinalstatement");
5544 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", (($this->getShowFinalStatement()) ?
"1" :
"0")));
5545 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5548 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5549 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"showinfo");
5550 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", (($this->getShowInfo()) ?
"1" :
"0")));
5551 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5554 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5555 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"mailnotification");
5556 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getMailNotification());
5557 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5560 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5561 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"mailnottype");
5562 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getMailNotificationType());
5563 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5566 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5567 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"exportsettings");
5568 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getExportSettings());
5569 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5572 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5573 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"forcejs");
5574 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", (($this->getForceJS()) ?
"1" :
"0")));
5575 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5578 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5579 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"customstyle");
5580 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getCustomStyle());
5581 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5584 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5585 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"shuffle_questions");
5586 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getShuffleQuestions()));
5587 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5590 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5591 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"processing_time");
5592 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getProcessingTime());
5593 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5596 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5597 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"enable_examview");
5598 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->getEnableExamview());
5599 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5602 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5603 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"show_examview_html");
5604 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->getShowExamviewHtml());
5605 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5608 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5609 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"show_examview_pdf");
5610 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->getShowExamviewPdf());
5611 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5614 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5615 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"enable_archiving");
5616 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->getEnableArchiving());
5617 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5620 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5621 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"sign_submission");
5622 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->getSignSubmission());
5623 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5626 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5627 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"char_selector_availability");
5628 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
"%d", $this->getCharSelectorAvailability()));
5629 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5632 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5633 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"char_selector_definition");
5634 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getCharSelectorDefinition());
5635 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5638 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5639 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"skill_service");
5640 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->isSkillServiceEnabled());
5641 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5644 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5645 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"result_tax_filters");
5646 $a_xml_writer->xmlElement(
"fieldentry",
null, serialize($this->getResultFilterTaxIds()));
5647 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5650 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5651 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"show_grading_status");
5652 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->isShowGradingStatusEnabled());
5653 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5656 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5657 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"show_grading_mark");
5658 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->isShowGradingMarkEnabled());
5659 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5663 if ($this->getStartingTime()) {
5664 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5665 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"starting_time");
5666 $backward_compatibility_format = $this->buildIso8601PeriodFromUnixtimeForExportCompatibility($this->starting_time);
5667 $a_xml_writer->xmlElement(
"fieldentry",
null, $backward_compatibility_format);
5668 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5671 if ($this->getEndingTime()) {
5672 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5673 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"ending_time");
5674 $backward_compatibility_format = $this->buildIso8601PeriodFromUnixtimeForExportCompatibility($this->ending_time);
5675 $a_xml_writer->xmlElement(
"fieldentry",
null, $backward_compatibility_format);
5676 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5681 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5682 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"activation_limited");
5683 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->isActivationLimited());
5684 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5687 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5688 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"activation_start_time");
5689 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->getActivationStartingTime());
5690 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5693 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5694 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"activation_end_time");
5695 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->getActivationEndingTime());
5696 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5699 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5700 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"activation_visibility");
5701 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->getActivationVisibility());
5702 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5705 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5706 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"autosave");
5707 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->getAutosave());
5708 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5711 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5712 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"autosave_ival");
5713 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getAutosaveIval());
5714 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5717 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5718 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"offer_question_hints");
5719 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->isOfferingQuestionHintsEnabled());
5720 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5723 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5724 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"instant_feedback_specific");
5725 $a_xml_writer->xmlElement(
"fieldentry",
null, $this->getSpecificAnswerFeedback());
5726 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5729 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5730 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"instant_feedback_answer_fixation");
5731 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->isInstantFeedbackAnswerFixationEnabled());
5732 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5735 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5736 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"obligations_enabled");
5737 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->areObligationsEnabled());
5738 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5741 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5742 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"enable_processing_time");
5743 $a_xml_writer->xmlElement(
"fieldentry",
null, (
int) $this->getEnableProcessingTime());
5744 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5746 foreach ($this->mark_schema->mark_steps as
$index => $mark) {
5748 $a_xml_writer->xmlStartTag(
"qtimetadatafield");
5749 $a_xml_writer->xmlElement(
"fieldlabel",
null,
"mark_step_$index");
5750 $a_xml_writer->xmlElement(
"fieldentry",
null, sprintf(
5751 "<short>%s</short><official>%s</official><percentage>%.2f</percentage><passed>%d</passed>",
5752 $mark->getShortName(),
5753 $mark->getOfficialName(),
5754 $mark->getMinimumLevel(),
5757 $a_xml_writer->xmlEndTag(
"qtimetadatafield");
5759 $a_xml_writer->xmlEndTag(
"qtimetadata");
5762 $a_xml_writer->xmlStartTag(
"objectives");
5763 $this->addQTIMaterial($a_xml_writer, $this->getIntroduction());
5764 $a_xml_writer->xmlEndTag(
"objectives");
5767 if ($this->getInstantFeedbackSolution() == 1) {
5769 "solutionswitch" =>
"Yes"
5774 $a_xml_writer->xmlElement(
"assessmentcontrol", $attrs,
null);
5776 if (strlen($this->getFinalStatement())) {
5778 $a_xml_writer->xmlStartTag(
"presentation_material");
5779 $a_xml_writer->xmlStartTag(
"flow_mat");
5780 $this->addQTIMaterial($a_xml_writer, $this->getFinalStatement());
5781 $a_xml_writer->xmlEndTag(
"flow_mat");
5782 $a_xml_writer->xmlEndTag(
"presentation_material");
5788 $a_xml_writer->xmlElement(
"section", $attrs,
null);
5789 $a_xml_writer->xmlEndTag(
"assessment");
5790 $a_xml_writer->xmlEndTag(
"questestinterop");
5792 $xml = $a_xml_writer->xmlDumpMem(
false);
5804 preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $date_time, $matches);
5805 $iso8601_period = sprintf(
"P%dY%dM%dDT%dH%dM%dS", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]);
5806 return $iso8601_period;
5818 $ilBench =
$DIC[
'ilBench'];
5820 $this->mob_ids = array();
5821 $this->file_ids = array();
5824 $this->exportXMLMetaData($a_xml_writer);
5827 $expLog->write(date(
"[y-m-d H:i:s] ") .
"Start Export Page Objects");
5828 $ilBench->start(
"ContentObjectExport",
"exportPageObjects");
5829 $this->exportXMLPageObjects($a_xml_writer, $a_inst, $expLog);
5830 $ilBench->stop(
"ContentObjectExport",
"exportPageObjects");
5831 $expLog->write(date(
"[y-m-d H:i:s] ") .
"Finished Export Page Objects");
5834 $expLog->write(date(
"[y-m-d H:i:s] ") .
"Start Export Media Objects");
5835 $ilBench->start(
"ContentObjectExport",
"exportMediaObjects");
5836 $this->exportXMLMediaObjects($a_xml_writer, $a_inst, $a_target_dir, $expLog);
5837 $ilBench->stop(
"ContentObjectExport",
"exportMediaObjects");
5838 $expLog->write(date(
"[y-m-d H:i:s] ") .
"Finished Export Media Objects");
5841 $expLog->write(date(
"[y-m-d H:i:s] ") .
"Start Export File Items");
5842 $ilBench->start(
"ContentObjectExport",
"exportFileItems");
5843 $this->exportFileItems($a_target_dir, $expLog);
5844 $ilBench->stop(
"ContentObjectExport",
"exportFileItems");
5845 $expLog->write(date(
"[y-m-d H:i:s] ") .
"Finished Export File Items");
5856 $md2xml =
new ilMD2XML($this->
getId(), 0, $this->getType());
5857 $md2xml->setExportMode(
true);
5858 $md2xml->startExport();
5859 $a_xml_writer->appendXML($md2xml->getXML());
5869 if ($a_tag ==
"Identifier" && $a_param ==
"Entry") {
5886 $ilBench =
$DIC[
'ilBench'];
5888 foreach ($this->questions as $question_id) {
5889 $ilBench->start(
"ContentObjectExport",
"exportPageObject");
5890 $expLog->write(date(
"[y-m-d H:i:s] ") .
"Page Object " . $question_id);
5893 $a_xml_writer->xmlStartTag(
"PageObject", $attrs);
5897 $ilBench->start(
"ContentObjectExport",
"exportPageObject_XML");
5899 $page_object->buildDom();
5900 $page_object->insertInstIntoIDs($a_inst);
5901 $mob_ids = $page_object->collectMediaObjects(
false);
5903 $xml = $page_object->getXMLFromDom(
false,
false,
false,
"",
true);
5904 $xml = str_replace(
"&",
"&",
$xml);
5905 $a_xml_writer->appendXML(
$xml);
5906 $page_object->freeDom();
5907 unset($page_object);
5909 $ilBench->stop(
"ContentObjectExport",
"exportPageObject_XML");
5912 $ilBench->start(
"ContentObjectExport",
"exportPageObject_CollectMedia");
5914 foreach ($mob_ids as $mob_id) {
5915 $this->mob_ids[$mob_id] = $mob_id;
5917 $ilBench->stop(
"ContentObjectExport",
"exportPageObject_CollectMedia");
5920 $ilBench->start(
"ContentObjectExport",
"exportPageObject_CollectFileItems");
5922 foreach ($file_ids as $file_id) {
5923 $this->file_ids[$file_id] = $file_id;
5925 $ilBench->stop(
"ContentObjectExport",
"exportPageObject_CollectFileItems");
5927 $a_xml_writer->xmlEndTag(
"PageObject");
5930 $ilBench->stop(
"ContentObjectExport",
"exportPageObject");
5939 foreach ($this->mob_ids as $mob_id) {
5940 $expLog->write(date(
"[y-m-d H:i:s] ") .
"Media Object " . $mob_id);
5943 $media_obj->exportXML($a_xml_writer, $a_inst);
5944 $media_obj->exportFiles($a_target_dir);
5956 foreach ($this->file_ids as $file_id) {
5957 $expLog->write(date(
"[y-m-d H:i:s] ") .
"File Item " . $file_id);
5958 $file_dir = $target_dir .
'/objects/il_' .
IL_INST_ID .
'_file_' . $file_id;
5960 $file_obj =
new ilObjFile($file_id,
false);
5961 $source_file = $file_obj->getFile($file_obj->getVersion());
5962 if (!is_file($source_file)) {
5963 $source_file = $file_obj->getFile();
5965 if (is_file($source_file)) {
5966 copy($source_file, $file_dir .
'/' . $file_obj->getFileName());
5986 return $this->canShowEctsGrades() && $this->canEditMarks();
5994 return (
bool) $this->getReportingDate();
6000 public function getECTSGrade($passed_array, $reached_points, $max_points): string
6002 return self::_getECTSGrade($passed_array, $reached_points, $max_points, $this->ects_grades[
"A"], $this->ects_grades[
"B"], $this->ects_grades[
"C"], $this->ects_grades[
"D"], $this->ects_grades[
"E"], $this->ects_fx);
6012 $passed_statistics->setData($points_passed);
6013 $ects_percentiles = array(
6014 "A" => $passed_statistics->quantile(
$a),
6015 "B" => $passed_statistics->quantile(
$b),
6016 "C" => $passed_statistics->quantile(
$c),
6017 "D" => $passed_statistics->quantile(
$d),
6018 "E" => $passed_statistics->quantile(
$e)
6020 if (count($points_passed) && ($reached_points >= $ects_percentiles[
"A"])) {
6022 } elseif (count($points_passed) && ($reached_points >= $ects_percentiles[
"B"])) {
6024 } elseif (count($points_passed) && ($reached_points >= $ects_percentiles[
"C"])) {
6026 } elseif (count($points_passed) && ($reached_points >= $ects_percentiles[
"D"])) {
6028 } elseif (count($points_passed) && ($reached_points >= $ects_percentiles[
"E"])) {
6030 } elseif (strcmp($fx,
"") != 0) {
6031 if ($max_points > 0) {
6032 $percentage = ($reached_points / $max_points) * 100.0;
6033 if ($percentage < 0) {
6039 if ($percentage >= $fx) {
6054 return $this->mark_schema->checkMarks();
6062 return $this->mark_schema;
6070 return $this->getTestId();
6075 public function onMarkSchemaSaved()
6083 $component_repository =
$DIC[
'component.repository'];
6084 $tree =
$DIC[
'tree'];
6087 $this->saveCompleteStatus($testQuestionSetConfigFactory->getQuestionSetConfig());
6089 if ($this->participantDataExist()) {
6090 $this->recalculateScores(
true);
6099 $total = $this->evalTotalPersons();
6101 $reporting_date = $this->getScoreSettings()->getResultSummarySettings()->getReportingDate();
6102 if ($reporting_date !==
null) {
6103 return $reporting_date <=
new DateTimeImmutable(
'now',
new DateTimeZone(
'UTC'));
6120 $this->author = $author;
6134 $md =
new ilMD($this->
getId(), 0, $this->getType());
6135 $md_life = $md->getLifecycle();
6137 if (strlen($a_author) == 0) {
6140 $a_author =
$ilUser->getFullname();
6143 $md_life = $md->addLifecycle();
6145 $con = $md_life->addContribute();
6146 $con->setRole(
"Author");
6148 $ent = $con->addEntity();
6149 $ent->setEntity($a_author);
6159 $this->saveAuthorToMetadata();
6172 $md =
new ilMD($this->
getId(), 0, $this->getType());
6173 $md_life = $md->getLifecycle();
6175 $ids = $md_life->getContributeIds();
6176 foreach ($ids as
$id) {
6177 $md_cont = $md_life->getContribute(
$id);
6178 if (strcmp($md_cont->getRole(),
"Author") == 0) {
6179 $entids = $md_cont->getEntityIds();
6180 foreach ($entids as $entid) {
6181 $md_ent = $md_cont->getEntity($entid);
6182 array_push($author, $md_ent->getEntity());
6187 return join(
",", $author);
6200 $md =
new ilMD($obj_id, 0,
"tst");
6201 $md_life = $md->getLifecycle();
6203 $ids = $md_life->getContributeIds();
6204 foreach ($ids as
$id) {
6205 $md_cont = $md_life->getContribute(
$id);
6206 if (strcmp($md_cont->getRole(),
"Author") == 0) {
6207 $entids = $md_cont->getEntityIds();
6208 foreach ($entids as $entid) {
6209 $md_ent = $md_cont->getEntity($entid);
6210 array_push($author, $md_ent->getEntity());
6215 return join(
",", $author);
6230 $result_array = array();
6231 $tests = array_slice(
6239 if (count($tests)) {
6242 if ($use_object_id) {
6244 $result_array[$obj_id] = $titles[
$ref_id];
6250 return $result_array;
6261 public function cloneObject(
int $target_id,
int $copy_id = 0,
bool $omit_tree =
false): ?
ilObject
6266 $certificateLogger =
$DIC->logger()->cert();
6267 $tree =
$DIC[
'tree'];
6269 $component_repository =
$DIC[
'component.repository'];
6271 $this->loadFromDb();
6275 $newObj = parent::cloneObject(
$target_id, $copy_id, $omit_tree);
6276 $newObj->setTmpCopyWizardCopyId($copy_id);
6277 $this->cloneMetaData($newObj);
6281 if ($cp_options->isRootNode($this->getRefId())) {
6282 $newObj->setOfflineStatus(
true);
6284 $newObj->setOfflineStatus($this->getOfflineStatus());
6288 $newObj->setAnonymity($this->getAnonymity());
6289 $newObj->setAnswerFeedback($this->getAnswerFeedback());
6290 $newObj->setAnswerFeedbackPoints($this->getAnswerFeedbackPoints());
6291 $newObj->setAuthor($this->getAuthor());
6292 $newObj->setLimitUsersEnabled($this->isLimitUsersEnabled());
6293 $newObj->setAllowedUsers($this->getAllowedUsers());
6294 $newObj->setAllowedUsersTimeGap($this->getAllowedUsersTimeGap());
6295 $newObj->setECTSFX($this->getECTSFX());
6296 $newObj->setECTSGrades($this->getECTSGrades());
6297 $newObj->setECTSOutput($this->getECTSOutput());
6298 $newObj->setEnableProcessingTime($this->getEnableProcessingTime());
6299 $newObj->setEndingTimeEnabled($this->isEndingTimeEnabled());
6300 $newObj->setEndingTime($this->getEndingTime());
6301 $newObj->setFixedParticipants($this->getFixedParticipants());
6302 $newObj->setInstantFeedbackSolution($this->getInstantFeedbackSolution());
6303 $newObj->setIntroductionEnabled($this->isIntroductionEnabled());
6304 $newObj->setIntroduction($this->getIntroduction());
6305 $newObj->setFinalStatement($this->getFinalStatement());
6306 $newObj->setShowInfo($this->getShowInfo());
6307 $newObj->setForceJS($this->getForceJS());
6308 $newObj->setCustomStyle($this->getCustomStyle());
6309 $newObj->setKiosk($this->getKiosk());
6310 $newObj->setShowFinalStatement($this->getShowFinalStatement());
6311 $newObj->setListOfQuestionsSettings($this->getListOfQuestionsSettings());
6312 $newObj->setMailNotification($this->getMailNotification());
6313 $newObj->setMailNotificationType($this->getMailNotificationType());
6314 $newObj->setNrOfTries($this->getNrOfTries());
6315 $newObj->setBlockPassesAfterPassedEnabled($this->isBlockPassesAfterPassedEnabled());
6316 $newObj->setPasswordEnabled($this->isPasswordEnabled());
6317 $newObj->setPassword($this->getPassword());
6318 $newObj->setProcessingTime($this->getProcessingTime());
6319 $newObj->setQuestionSetType($this->getQuestionSetType());
6320 $newObj->setReportingDate($this->getReportingDate());
6321 $newObj->setResetProcessingTime($this->getResetProcessingTime());
6322 $newObj->setShowGradingStatusEnabled($this->isShowGradingStatusEnabled());
6323 $newObj->setShowGradingMarkEnabled($this->isShowGradingMarkEnabled());
6324 $newObj->setSequenceSettings($this->getSequenceSettings());
6325 $newObj->setShowCancel($this->getShowCancel());
6326 $newObj->setShowMarker($this->getShowMarker());
6327 $newObj->setShuffleQuestions($this->getShuffleQuestions());
6328 $newObj->setStartingTimeEnabled($this->isStartingTimeEnabled());
6329 $newObj->setStartingTime($this->getStartingTime());
6330 $newObj->setTitleOutput($this->getTitleOutput());
6331 $newObj->setUsePreviousAnswers($this->getUsePreviousAnswers());
6332 $newObj->setRedirectionMode($this->getRedirectionMode());
6333 $newObj->setRedirectionUrl($this->getRedirectionUrl());
6334 $newObj->mark_schema = clone $this->mark_schema;
6335 $newObj->setEnabledViewMode($this->getEnabledViewMode());
6336 $newObj->setTemplate($this->getTemplate());
6337 $newObj->setShowExamIdInTestPassEnabled($this->isShowExamIdInTestPassEnabled());
6338 $newObj->setEnableExamView($this->getEnableExamview());
6339 $newObj->setShowExamViewHtml($this->getShowExamviewHtml());
6340 $newObj->setShowExamViewPdf($this->getShowExamviewPdf());
6341 $newObj->setEnableArchiving($this->getEnableArchiving());
6342 $newObj->setSignSubmission($this->getSignSubmission());
6343 $newObj->setCharSelectorAvailability($this->getCharSelectorAvailability());
6344 $newObj->setCharSelectorDefinition($this->getCharSelectorDefinition());
6345 $newObj->setSkillServiceEnabled($this->isSkillServiceEnabled());
6346 $newObj->setFollowupQuestionAnswerFixationEnabled($this->isFollowupQuestionAnswerFixationEnabled());
6347 $newObj->setInstantFeedbackAnswerFixationEnabled($this->isInstantFeedbackAnswerFixationEnabled());
6348 $newObj->setForceInstantFeedbackEnabled($this->isForceInstantFeedbackEnabled());
6349 $newObj->setAutosave($this->getAutosave());
6350 $newObj->setAutosaveIval($this->getAutosaveIval());
6351 $newObj->setOfferingQuestionHintsEnabled($this->isOfferingQuestionHintsEnabled());
6352 $newObj->setSpecificAnswerFeedback($this->getSpecificAnswerFeedback());
6353 if ($this->isPassWaitingEnabled()) {
6354 $newObj->setPassWaiting($this->getPassWaiting());
6356 $newObj->setObligationsEnabled($this->areObligationsEnabled());
6357 $newObj->saveToDb();
6366 $templateRepository,
6367 $DIC->filesystem()->web(),
6372 $cloneAction->cloneCertificate($this, $newObj);
6375 $testQuestionSetConfigFactory->getQuestionSetConfig()->cloneQuestionSetRelatedData($newObj);
6376 $newObj->saveQuestionsToDb();
6379 $skillLevelThresholdList->setTestId($this->getTestId());
6380 $skillLevelThresholdList->loadFromDb();
6381 $skillLevelThresholdList->cloneListForTest($newObj->getTestId());
6383 $newObj->saveToDb();
6384 $newObj->updateMetaData();
6386 $score_settings = $this->getScoreSettingsRepository()->getForObjFi($this->
getId());
6387 $this->getScoreSettingsRepository()->store(
6388 $score_settings->
withTestId($newObj->getTestId())
6392 $obj_settings->cloneSettings($newObj->getId());
6401 if ($this->isRandomTest()) {
6403 $tree =
$DIC[
'tree'];
6405 $component_repository =
$DIC[
'component.repository'];
6410 $component_repository,
6414 $questionSetConfig->loadFromDb();
6416 if ($questionSetConfig->isQuestionAmountConfigurationModePerPool()) {
6423 $sourcePoolDefinitionList->loadDefinitions();
6425 if (is_int($sourcePoolDefinitionList->getQuestionAmount())) {
6426 $num = $sourcePoolDefinitionList->getQuestionAmount();
6428 } elseif (is_int($questionSetConfig->getQuestionAmountPerTest())) {
6429 $num = $questionSetConfig->getQuestionAmountPerTest();
6432 $this->loadQuestions();
6433 $num = count($this->questions);
6441 if ($this->isRandomTest()) {
6442 return $this->getQuestionCount();
6444 return count($this->questions);
6460 if (strcmp($question_id,
"") != 0) {
6478 $result =
$ilDB->queryF(
6479 "SELECT obj_fi FROM tst_tests WHERE test_id = %s",
6483 if ($result->numRows()) {
6484 $row =
$ilDB->fetchAssoc($result);
6485 $object_id = $row[
"obj_fi"];
6502 $result =
$ilDB->queryF(
6503 "SELECT tst_tests.obj_fi FROM tst_tests, tst_active WHERE tst_tests.test_id = tst_active.test_fi AND tst_active.active_id = %s",
6507 if ($result->numRows()) {
6508 $row =
$ilDB->fetchAssoc($result);
6509 $object_id = $row[
"obj_fi"];
6526 $result =
$ilDB->queryF(
6527 "SELECT test_id FROM tst_tests WHERE obj_fi = %s",
6531 if ($result->numRows()) {
6532 $row =
$ilDB->fetchAssoc($result);
6533 $test_id = $row[
"test_id"];
6551 if (!$active_id || !$question_id) {
6552 if ($pass ===
null) {
6555 if ($pass ===
null) {
6558 $result =
$ilDB->queryF(
6559 "SELECT value1 FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
6560 array(
'integer',
'integer',
'integer'),
6561 array($active_id, $question_id, $pass)
6563 if ($result->numRows() == 1) {
6564 $row =
$ilDB->fetchAssoc($result);
6565 return $row[
"value1"];
6585 $result =
$ilDB->queryF(
6586 "SELECT question_text FROM qpl_questions WHERE question_id = %s",
6590 if ($result->numRows() == 1) {
6591 $row =
$ilDB->fetchAssoc($result);
6592 $res = $row[
"question_text"];
6604 $participantList->initializeFromDbRows($this->getInvitedUsers());
6606 return $participantList;
6615 $participantList->initializeFromDbRows($this->getTestParticipants());
6617 return $participantList;
6626 public function &
getInvitedUsers($user_id =
"", $order =
"login, lastname, firstname"): array
6631 $result_array = array();
6633 if ($this->getAnonymity()) {
6634 if (is_numeric($user_id)) {
6635 $result =
$ilDB->queryF(
6636 "SELECT tst_active.active_id, tst_active.tries, usr_id, %s login, %s lastname, %s firstname, tst_invited_user.clientip, " .
6637 "tst_active.submitted test_finished, matriculation, COALESCE(tst_active.last_finished_pass, -1) <> tst_active.last_started_pass unfinished_passes FROM usr_data, tst_invited_user " .
6638 "LEFT JOIN tst_active ON tst_active.user_fi = tst_invited_user.user_fi AND tst_active.test_fi = tst_invited_user.test_fi " .
6639 "WHERE tst_invited_user.test_fi = %s and tst_invited_user.user_fi=usr_data.usr_id AND usr_data.usr_id=%s " .
6641 array(
'text',
'text',
'text',
'integer',
'integer'),
6642 array(
"", $this->
lng->txt(
"anonymous"),
"", $this->getTestId(), $user_id)
6645 $result =
$ilDB->queryF(
6646 "SELECT tst_active.active_id, tst_active.tries, usr_id, %s login, %s lastname, %s firstname, tst_invited_user.clientip, " .
6647 "tst_active.submitted test_finished, matriculation, COALESCE(tst_active.last_finished_pass, -1) <> tst_active.last_started_pass unfinished_passes FROM usr_data, tst_invited_user " .
6648 "LEFT JOIN tst_active ON tst_active.user_fi = tst_invited_user.user_fi AND tst_active.test_fi = tst_invited_user.test_fi " .
6649 "WHERE tst_invited_user.test_fi = %s and tst_invited_user.user_fi=usr_data.usr_id " .
6651 array(
'text',
'text',
'text',
'integer'),
6652 array(
"", $this->
lng->txt(
"anonymous"),
"", $this->getTestId())
6656 if (is_numeric($user_id)) {
6657 $result =
$ilDB->queryF(
6658 "SELECT tst_active.active_id, tst_active.tries, usr_id, login, lastname, firstname, tst_invited_user.clientip, " .
6659 "tst_active.submitted test_finished, matriculation, COALESCE(tst_active.last_finished_pass, -1) <> tst_active.last_started_pass unfinished_passes FROM usr_data, tst_invited_user " .
6660 "LEFT JOIN tst_active ON tst_active.user_fi = tst_invited_user.user_fi AND tst_active.test_fi = tst_invited_user.test_fi " .
6661 "WHERE tst_invited_user.test_fi = %s and tst_invited_user.user_fi=usr_data.usr_id AND usr_data.usr_id=%s " .
6663 array(
'integer',
'integer'),
6664 array($this->getTestId(), $user_id)
6667 $result =
$ilDB->queryF(
6668 "SELECT tst_active.active_id, tst_active.tries, usr_id, login, lastname, firstname, tst_invited_user.clientip, " .
6669 "tst_active.submitted test_finished, matriculation, COALESCE(tst_active.last_finished_pass, -1) <> tst_active.last_started_pass unfinished_passes FROM usr_data, tst_invited_user " .
6670 "LEFT JOIN tst_active ON tst_active.user_fi = tst_invited_user.user_fi AND tst_active.test_fi = tst_invited_user.test_fi " .
6671 "WHERE tst_invited_user.test_fi = %s and tst_invited_user.user_fi=usr_data.usr_id " .
6674 array($this->getTestId())
6678 $result_array = array();
6679 while ($row =
$ilDB->fetchAssoc($result)) {
6680 $result_array[$row[
'usr_id']] = $row;
6682 return $result_array;
6696 if ($this->getAnonymity()) {
6698 SELECT tst_active.active_id,
6700 tst_active.user_fi usr_id,
6704 tst_active.submitted test_finished,
6705 usr_data.matriculation,
6707 tst_active.lastindex,
6708 COALESCE(tst_active.last_finished_pass, -1) <> tst_active.last_started_pass unfinished_passes
6711 ON tst_active.user_fi = usr_data.usr_id
6712 WHERE tst_active.test_fi = %s
6713 ORDER BY usr_data.lastname
6715 $result =
$ilDB->queryF(
6717 array(
'text',
'text',
'text',
'integer'),
6718 array(
"", $this->
lng->txt(
"anonymous"),
"", $this->getTestId())
6722 SELECT tst_active.active_id,
6724 tst_active.user_fi usr_id,
6728 tst_active.submitted test_finished,
6729 usr_data.matriculation,
6731 tst_active.lastindex,
6732 COALESCE(tst_active.last_finished_pass, -1) <> tst_active.last_started_pass unfinished_passes
6735 ON tst_active.user_fi = usr_data.usr_id
6736 WHERE tst_active.test_fi = %s
6737 ORDER BY usr_data.lastname
6739 $result =
$ilDB->queryF(
6742 array($this->getTestId())
6746 while ($row =
$ilDB->fetchAssoc($result)) {
6747 $data[$row[
'active_id']] = $row;
6750 if (strlen(trim($participant[
"firstname"] . $participant[
"lastname"])) == 0) {
6763 if (count($scoring) == 0) {
6767 $participants = &$this->getTestParticipants();
6768 $filtered_participants = array();
6769 foreach ($participants as $active_id => $participant) {
6770 $qstType_IN_manScoreableQstTypes =
$ilDB->in(
'qpl_questions.question_type_fi', $scoring,
false,
'integer');
6773 SELECT tst_test_result.manual
6775 FROM tst_test_result
6777 INNER JOIN qpl_questions
6778 ON tst_test_result.question_fi = qpl_questions.question_id
6780 WHERE tst_test_result.active_fi = %s
6781 AND $qstType_IN_manScoreableQstTypes
6784 $result =
$ilDB->queryF(
6790 $count = $result->numRows();
6795 if ($participant[
'active']) {
6796 $filtered_participants[$active_id] = $participant;
6800 if (!$participant[
'active']) {
6801 $filtered_participants[$active_id] = $participant;
6805 $filtered_participants[$active_id] = $participant;
6808 $assessmentSetting =
new ilSetting(
"assessment");
6809 $manscoring_done = $assessmentSetting->get(
"manscoring_done_" . $active_id);
6810 if ($manscoring_done) {
6811 $filtered_participants[$active_id] = $participant;
6815 $assessmentSetting =
new ilSetting(
"assessment");
6816 $manscoring_done = $assessmentSetting->get(
"manscoring_done_" . $active_id);
6817 if (!$manscoring_done) {
6818 $filtered_participants[$active_id] = $participant;
6824 while ($row =
$ilDB->fetchAssoc($result)) {
6825 if ($row[
"manual"]) {
6829 if (($found > 0) && ($found < $count)) {
6830 $filtered_participants[$active_id] = $participant;
6834 $filtered_participants[$active_id] = $participant;
6839 return $filtered_participants;
6853 if (!is_array($ids) || count($ids) == 0) {
6857 if ($this->getAnonymity()) {
6858 $result =
$ilDB->queryF(
6859 "SELECT usr_id, %s login, %s lastname, %s firstname, client_ip clientip FROM usr_data WHERE " .
$ilDB->in(
'usr_id', $ids,
false,
'integer') .
" ORDER BY login",
6860 array(
'text',
'text',
'text'),
6861 array(
"", $this->
lng->txt(
"anonymous"),
"")
6864 $result =
$ilDB->query(
"SELECT usr_id, login, lastname, firstname, client_ip clientip FROM usr_data WHERE " .
$ilDB->in(
'usr_id', $ids,
false,
'integer') .
" ORDER BY login");
6867 $result_array = array();
6868 while ($row =
$ilDB->fetchAssoc($result)) {
6869 $result_array[$row[
"usr_id"]] = $row;
6871 return $result_array;
6876 if (!is_array($ids) || count($ids) == 0) {
6889 if (!is_array($ids) || count($ids) == 0) {
6893 foreach ($ids as $obj_id) {
6909 $members = $group->getGroupMemberIds();
6910 foreach ($members as $user_id) {
6924 $rbacreview =
$DIC[
'rbacreview'];
6925 $members = $rbacreview->assignedUsers($role_id);
6926 foreach ($members as $user_id) {
6944 $affectedRows =
$ilDB->manipulateF(
6945 "DELETE FROM tst_invited_user WHERE test_fi = %s AND user_fi = %s",
6946 array(
'integer',
'integer'),
6947 array($this->getTestId(), $user_id)
6963 "DELETE FROM tst_invited_user WHERE test_fi = %s AND user_fi = %s",
6964 array(
'integer',
'integer'),
6965 array($this->getTestId(), $user_id)
6968 "INSERT INTO tst_invited_user (test_fi, user_fi, clientip, tstamp) VALUES (%s, %s, %s, %s)",
6969 array(
'integer',
'integer',
'text',
'integer'),
6970 array($this->getTestId(), $user_id, (strlen($client_ip)) ? $client_ip :
null, time())
6980 $affectedRows =
$ilDB->manipulateF(
6981 "UPDATE tst_invited_user SET clientip = %s, tstamp = %s WHERE test_fi=%s and user_fi=%s",
6982 array(
'text',
'integer',
'integer',
'integer'),
6983 array((strlen($client_ip)) ? $client_ip :
null, time(), $this->getTestId(), $user_id)
6996 if (is_numeric($question_fi)) {
6997 $result =
$ilDB->queryF(
6998 "SELECT question_fi, solved FROM tst_qst_solved WHERE active_fi = %s AND question_fi=%s",
6999 array(
'integer',
'integer'),
7000 array($active_id, $question_fi)
7003 $result =
$ilDB->queryF(
7004 "SELECT question_fi, solved FROM tst_qst_solved WHERE active_fi = %s",
7009 $result_array = array();
7010 while ($row =
$ilDB->fetchAssoc($result)) {
7011 $result_array[$row[
"question_fi"]] = $row;
7013 return $result_array;
7025 $active_id = $this->getActiveIdOfUser($user_id);
7027 "DELETE FROM tst_qst_solved WHERE active_fi = %s AND question_fi = %s",
7028 array(
'integer',
'integer'),
7029 array($active_id, $question_id)
7032 "INSERT INTO tst_qst_solved (solved, question_fi, active_fi) VALUES (%s, %s, %s)",
7033 array(
'integer',
'integer',
'integer'),
7034 array($value, $question_id, $active_id)
7046 $result =
$ilDB->queryF(
7047 "SELECT submitted FROM tst_active WHERE active_id=%s AND submitted=%s",
7048 array(
'integer',
'integer'),
7049 array($active_id, 1)
7051 return $result->numRows() == 1;
7063 if (!is_numeric($user_id)) {
7067 $result =
$ilDB->queryF(
7068 "SELECT submitted FROM tst_active WHERE test_fi=%s AND user_fi=%s AND submitted=%s",
7069 array(
'integer',
'integer',
'integer'),
7070 array($this->getTestId(), $user_id, 1)
7072 return $result->numRows() == 1;
7080 return $this->getNrOfTries() != 0;
7091 return $tries >= $this->getNrOfTries();
7107 "user_id" => $this->
lng->txt(
"user_id"),
7108 "matriculation" => $this->lng->txt(
"matriculation"),
7109 "lastname" => $this->lng->txt(
"lastname"),
7110 "firstname" => $this->lng->txt(
"firstname"),
7111 "login" => $this->lng->txt(
"login"),
7112 "reached_points" => $this->lng->txt(
"tst_reached_points"),
7113 "max_points" => $this->lng->txt(
"tst_maximum_points"),
7114 "percent_value" => $this->lng->txt(
"tst_percent_solved"),
7115 "mark" => $this->lng->txt(
"tst_mark"),
7116 "ects" => $this->lng->txt(
"ects_grade"),
7117 "passed" => $this->lng->txt(
"tst_mark_passed"),
7120 if (count($participants)) {
7121 if ($this->getECTSOutput()) {
7122 $passed_array = &$this->getTotalPointsPassedArray();
7124 foreach ($participants as $active_id => $user_rec) {
7125 $mark = $ects_mark =
'';
7127 $reached_points = 0;
7131 if (!is_int($pass)) {
7134 foreach ($this->questions as $value) {
7136 if (is_object($question)) {
7137 $max_points += $question->getMaximumPoints();
7138 $reached_points += $question->getReachedPoints($active_id, $pass);
7141 if ($max_points > 0) {
7142 $percentvalue = $reached_points / $max_points;
7143 if ($percentvalue < 0) {
7144 $percentvalue = 0.0;
7149 $mark_obj = $this->mark_schema->getMatchingMark($percentvalue * 100);
7152 $mark = $mark_obj->getOfficialName();
7153 if ($this->getECTSOutput()) {
7154 $ects_mark = $this->getECTSGrade($passed_array, $reached_points, $max_points);
7157 if ($this->getAnonymity()) {
7158 $user_rec[
'firstname'] =
"";
7159 $user_rec[
'lastname'] = $this->
lng->txt(
"anonymous");
7162 "user_id" => $user_rec[
'usr_id'],
7163 "matriculation" => $user_rec[
'matriculation'],
7164 "lastname" => $user_rec[
'lastname'],
7165 "firstname" => $user_rec[
'firstname'],
7166 "login" => $user_rec[
'login'],
7167 "reached_points" => $reached_points,
7168 "max_points" => $max_points,
7169 "percent_value" => $percentvalue,
7171 "ects" => $ects_mark,
7172 "passed" => $user_rec[
'passed'] ?
'1' :
'0',
7174 $results[] = $prepareForCSV ? $this->processCSVRow($row,
true) : $row;
7190 public function &
processCSVRow($row, $quoteAll =
false, $separator =
";"): array
7192 $resultarray = array();
7193 foreach ($row as $rowindex => $entry) {
7198 if (strpos($entry,
"\"") !==
false) {
7199 $entry = str_replace(
"\"",
"\"\"", $entry);
7202 if (strpos($entry, $separator) !==
false) {
7206 $entry = str_replace(chr(13) . chr(10), chr(10), $entry);
7209 $entry =
"\"" . $entry .
"\"";
7212 $resultarray[$rowindex] = $entry;
7214 return $resultarray;
7229 $result =
$ilDB->queryF(
7230 "SELECT tries FROM tst_active WHERE active_id = %s",
7234 if ($result->numRows()) {
7235 $row =
$ilDB->fetchAssoc($result);
7236 return $row[
"tries"];
7255 $result =
$ilDB->queryF(
7256 "SELECT MAX(pass) maxpass FROM tst_pass_result WHERE active_fi = %s",
7261 if ($result->numRows()) {
7262 $row =
$ilDB->fetchAssoc($result);
7263 return $row[
"maxpass"];
7279 $result =
$ilDB->queryF(
7280 "SELECT * FROM tst_pass_result WHERE active_fi = %s",
7285 if (!$result->numRows()) {
7291 while ($row =
$ilDB->fetchAssoc($result)) {
7292 if ($row[
"maxpoints"] > 0.0) {
7293 $factor = (float) ($row[
"points"] / $row[
"maxpoints"]);
7297 if ($factor === 0.0 && $bestfactor === 0.0
7298 || $factor > $bestfactor) {
7300 $bestfactor = $factor;
7304 if (is_array($bestrow)) {
7305 return $bestrow[
"pass"];
7321 $counted_pass =
null;
7327 return $counted_pass;
7341 if ($this->isDynamicTest()) {
7343 $tree =
$DIC[
'tree'];
7347 $component_repository =
$DIC[
'component.repository'];
7350 $testSession = $testSessionFactory->getSession($active_id);
7353 $testSequence = $testSequenceFactory->getSequenceByTestSession($testSession);
7356 $dynamicQuestionSetConfig->loadFromDb();
7358 $testSequence->loadFromDb($dynamicQuestionSetConfig);
7361 return $testSequence->getTrackedQuestionCount();
7364 if ($this->isRandomTest()) {
7365 $this->loadQuestions($active_id, $pass);
7368 foreach ($this->questions as $value) {
7370 $workedthrough += 1;
7373 return $workedthrough;
7387 if (is_null($pass)) {
7392 SELECT tst_pass_result.tstamp pass_res_tstamp,
7393 tst_test_result.tstamp quest_res_tstamp
7395 FROM tst_pass_result
7397 LEFT JOIN tst_test_result
7398 ON tst_test_result.active_fi = tst_pass_result.active_fi
7399 AND tst_test_result.pass = tst_pass_result.pass
7401 WHERE tst_pass_result.active_fi = %s
7402 AND tst_pass_result.pass = %s
7404 ORDER BY tst_test_result.tstamp DESC
7407 $result =
$ilDB->queryF(
7409 array(
'integer',
'integer'),
7410 array($active_id, $pass)
7413 while ($row =
$ilDB->fetchAssoc($result)) {
7414 if ($row[
'quest_res_tstamp']) {
7415 return $row[
'quest_res_tstamp'];
7418 return $row[
'pass_res_tstamp'];
7432 public function isExecutable($testSession, $user_id, $allowPassIncrease =
false): array
7435 "executable" =>
true,
7436 "errormessage" =>
""
7438 if ($this->isDynamicTest()) {
7439 $result[
"executable"] =
false;
7440 $result[
"errormessage"] = ($this->
lng->txt(
"ctm_cannot_be_started"));
7443 if (!$this->startingTimeReached()) {
7444 $result[
"executable"] =
false;
7448 if ($this->endingTimeReached()) {
7449 $result[
"executable"] =
false;
7454 $active_id = $this->getActiveIdOfUser($user_id);
7456 if ($this->getEnableProcessingTime()) {
7457 if ($active_id > 0) {
7458 $starting_time = $this->getStartingTimeOfUser($active_id);
7459 if ($starting_time !==
false) {
7460 if ($this->isMaxProcessingTimeReached($starting_time, $active_id)) {
7461 if ($allowPassIncrease && $this->getResetProcessingTime() && (($this->getNrOfTries() == 0) || ($this->getNrOfTries() > (self::_getPass($active_id) + 1)))) {
7467 $testSession->increasePass();
7468 $testSession->setLastSequence(0);
7469 $testSession->saveToDb();
7471 $result[
"executable"] =
false;
7472 $result[
"errormessage"] = $this->
lng->txt(
"detail_max_processing_time_reached");
7481 $testPassesSelector->setActiveId($active_id);
7482 $testPassesSelector->setLastFinishedPass($testSession->getLastFinishedPass());
7484 if ($this->hasNrOfTriesRestriction() && ($active_id > 0)) {
7485 $closedPasses = $testPassesSelector->getClosedPasses();
7487 if (count($closedPasses) >= $this->getNrOfTries()) {
7488 $result[
"executable"] =
false;
7489 $result[
"errormessage"] = $this->
lng->txt(
"maximum_nr_of_tries_reached");
7493 if ($this->isBlockPassesAfterPassedEnabled() && !$testPassesSelector->openPassExists()) {
7495 $result[
'executable'] =
false;
7496 $result[
'errormessage'] = $this->
lng->txt(
"tst_addit_passes_blocked_after_passed_msg");
7501 if ($this->isPassWaitingEnabled() && $testPassesSelector->getLastFinishedPass() !==
null) {
7502 $lastPass = $testPassesSelector->getLastFinishedPassTimestamp();
7503 if ($lastPass && strlen($this->getPassWaiting())) {
7504 $pass_waiting_string = $this->getPassWaiting();
7505 $time_values = explode(
":", $pass_waiting_string);
7506 $next_pass_allowed = strtotime(
'+ ' . $time_values[0] .
' Months + ' . $time_values[1] .
' Days + ' . $time_values[2] .
' Hours' . $time_values[3] .
' Minutes', $lastPass);
7508 if (time() < $next_pass_allowed) {
7511 $result[
"executable"] =
false;
7512 $result[
"errormessage"] = sprintf($this->
lng->txt(
'wait_for_next_pass_hint_msg'), $date);
7525 $passSelector->setActiveId($testSession->
getActiveId());
7528 return $passSelector->hasReportablePasses();
7535 $passSelector->setActiveId($testSession->
getActiveId());
7538 return $passSelector->hasExistingPasses();
7552 if ($active_id < 1) {
7555 if ($pass ===
null) {
7556 $pass = ($this->getResetProcessingTime()) ? self::_getPass($active_id) : 0;
7558 $result =
$ilDB->queryF(
7559 "SELECT tst_times.started FROM tst_times WHERE tst_times.active_fi = %s AND tst_times.pass = %s ORDER BY tst_times.started",
7560 array(
'integer',
'integer'),
7561 array($active_id, $pass)
7563 if ($result->numRows()) {
7564 $row =
$ilDB->fetchAssoc($result);
7565 if (preg_match(
"/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row[
"started"], $matches)) {
7566 return mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
7583 if ($this->getEnableProcessingTime()) {
7584 $processing_time = $this->getProcessingTimeInSeconds($active_id);
7586 if ($now > ($starting_time + $processing_time)) {
7601 $tags_trafo = $this->
refinery->string()->stripTags();
7605 questtypes.type_tag,
7607 tstquest.obligatory,
7608 origquest.obj_fi orig_obj_fi
7610 FROM qpl_questions questions
7612 INNER JOIN qpl_qst_type questtypes
7613 ON questtypes.question_type_id = questions.question_type_fi
7615 INNER JOIN tst_test_question tstquest
7616 ON tstquest.question_fi = questions.question_id
7618 LEFT JOIN qpl_questions origquest
7619 ON origquest.question_id = questions.original_id
7621 WHERE tstquest.test_fi = %s
7623 ORDER BY tstquest.sequence
7626 $query_result =
$ilDB->queryF(
7629 array($this->getTestId())
7632 $questions = array();
7634 while ($row =
$ilDB->fetchAssoc($query_result)) {
7635 $row[
'title'] = $tags_trafo->transform($row[
'title']);
7636 $row[
'description'] = $tags_trafo->transform($row[
'description'] !==
'' && $row[
'description'] !==
null ? $row[
'description'] :
' ');
7637 $row[
'author'] = $tags_trafo->transform($row[
'author']);
7638 $row[
'obligationPossible'] = self::isQuestionObligationPossible($row[
'question_id']);
7640 $questions[] = $row;
7652 foreach ($this->getTestQuestions() as $questionData) {
7653 if ($questionData[
'question_id'] != $questionId) {
7667 $row =
$DIC->database()->fetchAssoc(
$DIC->database()->queryF(
7668 "SELECT COUNT(question_id) cnt FROM qpl_questions WHERE question_id = %s AND obj_fi = %s",
7669 array(
'integer',
'integer'),
7670 array($questionId, $this->
getId())
7673 return (
bool) $row[
'cnt'];
7683 foreach ($this->getTestQuestions() as $questionData) {
7684 $points += $questionData[
'points'];
7693 public function getPotentialRandomTestQuestions(): array
7703 questtypes.type_tag,
7704 origquest.obj_fi orig_obj_fi
7706 FROM qpl_questions questions
7708 INNER JOIN qpl_qst_type questtypes
7709 ON questtypes.question_type_id = questions.question_type_fi
7711 INNER JOIN tst_rnd_cpy tstquest
7712 ON tstquest.qst_fi = questions.question_id
7714 LEFT JOIN qpl_questions origquest
7715 ON origquest.question_id = questions.original_id
7717 WHERE tstquest.tst_fi = %s
7720 $query_result =
$ilDB->queryF(
7723 array($this->getTestId())
7726 $questions = array();
7728 while ($row =
$ilDB->fetchAssoc($query_result)) {
7731 $question[
'obligationPossible'] = self::isQuestionObligationPossible($row[
'question_id']);
7733 $questions[] = $question;
7747 return ($this->shuffle_questions) ? 1 : 0;
7758 $this->shuffle_questions = ($a_shuffle) ? 1 : 0;
7775 return ($this->show_summary) ? $this->show_summary : 0;
7792 $this->show_summary = $a_value;
7803 if (($this->show_summary & 1) > 0) {
7819 $this->show_summary = 1;
7821 $this->show_summary = 0;
7833 if (($this->show_summary & 2) > 0) {
7848 if ($a_value && $this->getListOfQuestions()) {
7849 $this->show_summary = $this->show_summary | 2;
7851 if (!$a_value && $this->getListOfQuestions()) {
7852 if ($this->getListOfQuestionsStart()) {
7853 $this->show_summary = $this->show_summary ^ 2;
7866 if (($this->show_summary & 4) > 0) {
7881 if ($a_value && $this->getListOfQuestions()) {
7882 $this->show_summary = $this->show_summary | 4;
7884 if (!$a_value && $this->getListOfQuestions()) {
7885 if ($this->getListOfQuestionsEnd()) {
7886 $this->show_summary = $this->show_summary ^ 4;
7896 if (($this->show_summary & 8) > 0) {
7911 if ($a_value && $this->getListOfQuestions()) {
7912 $this->show_summary = $this->show_summary | 8;
7914 if (!$a_value && $this->getListOfQuestions()) {
7915 if ($this->getListOfQuestionsDescription()) {
7916 $this->show_summary = $this->show_summary ^ 8;
7929 return $this->getScoreSettings()->getResultDetailsSettings()->getResultsPresentation();
7937 return $this->getScoreSettings()->getResultDetailsSettings()->getShowPassDetails();
7945 return $this->getScoreSettings()->getResultDetailsSettings()->getShowSolutionDetails();
7953 return $this->getScoreSettings()->getResultDetailsSettings()->getShowSolutionPrintview();
7960 return $this->getShowSolutionPrintview();
7968 return $this->getScoreSettings()->getResultDetailsSettings()->getShowSolutionFeedback();
7976 return $this->getScoreSettings()->getResultDetailsSettings()->getShowSolutionAnswersOnly();
7984 return $this->getScoreSettings()->getResultDetailsSettings()->getShowSolutionSignature();
7992 return $this->getScoreSettings()->getResultDetailsSettings()->getShowSolutionSuggested();
8001 return $this->getScoreSettings()->getResultDetailsSettings()->getShowSolutionListComparison();
8006 return $this->getScoreSettings()->getResultDetailsSettings()->getShowSolutionListOwnAnswers();
8018 $this->getScoreSettings()->getResultDetailsSettings()->withShowSolutionPrintview($a_printview === 1);
8033 $result =
$ilDB->queryF(
8034 "SELECT user_fi FROM tst_active WHERE active_id = %s",
8038 if ($result->numRows()) {
8039 $row =
$ilDB->fetchAssoc($result);
8040 return $row[
"user_fi"];
8048 return $this->limitUsersEnabled;
8053 $this->limitUsersEnabled = $limitUsersEnabled;
8058 return ($this->allowedUsers) ? $this->allowedUsers : 0;
8063 $this->allowedUsers = $a_allowed_users;
8068 return ($this->allowedUsersTimeGap) ? $this->allowedUsersTimeGap : 0;
8073 $this->allowedUsersTimeGap = $a_allowed_users_time_gap;
8081 $nr_of_users = $this->getAllowedUsers();
8082 $time_gap = ($this->getAllowedUsersTimeGap()) ? $this->getAllowedUsersTimeGap() : 60;
8083 if (($nr_of_users > 0) && ($time_gap > 0)) {
8085 $time_border = $now - $time_gap;
8086 $str_time_border = date(
"YmdHis", $time_border);
8088 SELECT DISTINCT tst_times.active_fi
8090 INNER JOIN tst_active
8091 ON tst_times.active_fi = tst_active.active_id
8093 tst_times.pass > tst_active.last_finished_pass OR tst_active.last_finished_pass IS NULL
8095 WHERE tst_times.tstamp > %s
8096 AND tst_active.test_fi = %s
8098 $result =
$ilDB->queryF(
$query, array(
'integer',
'integer'), array($time_border, $this->getTestId()));
8099 if ($result->numRows() >= $nr_of_users) {
8116 $result =
$ilDB->queryF(
8117 "SELECT finished FROM tst_times WHERE active_fi = %s ORDER BY finished DESC",
8121 if ($result->numRows()) {
8122 $row =
$ilDB->fetchAssoc($result);
8123 return $row[
"finished"];
8133 SELECT MAX(tst_times.tstamp) as last_pass_access
8135 WHERE active_fi = %s
8141 array(
'integer',
'integer'),
8142 array($activeId, $passIndex)
8145 while ($row =
$DIC->database()->fetchAssoc(
$res)) {
8146 return $row[
'last_pass_access'];
8161 if (preg_match(
"/<[^>]*?>/", $a_text)) {
8177 for (
$i = 0;
$i < $a_material->getMaterialCount();
$i++) {
8178 $material = $a_material->getMaterial(
$i);
8179 if (strcmp($material[
"type"],
"mattext") == 0) {
8180 $result .= $material[
"material"]->getContent();
8182 if (strcmp($material[
"type"],
"matimage") == 0) {
8183 $matimage = $material[
"material"];
8184 if (preg_match(
"/(il_([0-9]+)_mob_([0-9]+))/", $matimage->getLabel(), $matches)) {
8190 array_push($import_mob_xhtml, array(
"mob" => $matimage->getLabel(),
"uri" => $matimage->getUri()));
8195 $ilLog =
$DIC[
'ilLog'];
8196 $ilLog->write(print_r(
ilSession::get(
"import_mob_xhtml"),
true));
8208 $a_xml_writer->xmlStartTag(
"material");
8211 "texttype" =>
"text/plain"
8213 if ($this->isHTML($a_material)) {
8214 $attrs[
"texttype"] =
"text/xhtml";
8218 $a_xml_writer->xmlElement(
"mattext", $attrs,
$txt);
8221 foreach (
$mobs as $mob) {
8222 $moblabel =
"il_" .
IL_INST_ID .
"_mob_" . $mob;
8223 if (strpos($a_material,
"mm_$mob") !==
false) {
8227 "label" => $moblabel,
8228 "uri" =>
"objects/" .
"il_" .
IL_INST_ID .
"_mob_" . $mob .
"/" . $mob_obj->getTitle()
8231 $a_xml_writer->xmlElement(
"matimage", $imgattrs,
null);
8234 $a_xml_writer->xmlEndTag(
"material");
8245 if ($txt_output ==
null) {
8250 $prepare_for_latex_output,
8251 $omitNl2BrWhenTextArea
8263 return ($this->anonymity) ? 1 : 0;
8276 $this->anonymity = 1;
8279 $this->anonymity = 0;
8292 return ($this->show_cancel) ? 1 : 0;
8305 $this->show_cancel = 1;
8308 $this->show_cancel = 0;
8321 return ($this->show_marker) ? 1 : 0;
8334 $this->show_marker = 1;
8337 $this->show_marker = 0;
8350 return ($this->fixed_participants) ? 1 : 0;
8363 $this->fixed_participants = 1;
8366 $this->fixed_participants = 0;
8383 $result =
$ilDB->queryF(
8384 "SELECT anonymity FROM tst_tests WHERE obj_fi = %s",
8388 while ($row =
$ilDB->fetchAssoc($result)) {
8389 return $row[
'anonymity'];
8406 SELECT tst_tests.question_set_type
8408 INNER JOIN tst_tests
8409 ON tst_active.test_fi = tst_tests.test_id
8410 WHERE tst_active.active_id = %s
8415 while ($row =
$ilDB->fetchAssoc(
$res)) {
8416 return $row[
'question_set_type'];
8432 throw new Exception(__METHOD__ .
' is deprecated ... use ilObjTest::lookupQuestionSetTypeByActiveId() instead!');
8437 $result =
$ilDB->queryF(
8438 "SELECT tst_tests.random_test FROM tst_tests, tst_active WHERE tst_active.active_id = %s AND tst_active.test_fi = tst_tests.test_id",
8442 while ($row =
$ilDB->fetchAssoc($result)) {
8443 return $row[
'random_test'];
8458 public function userLookupFullName($user_id, $overwrite_anonymity =
false, $sorted_order =
false, $suffix =
""): string
8460 if ($this->getAnonymity() && !$overwrite_anonymity) {
8461 return $this->
lng->txt(
"anonymous") . $suffix;
8464 if (strlen($uname[
"firstname"] . $uname[
"lastname"]) == 0) {
8465 $uname[
"firstname"] = $this->
lng->txt(
"deleted_user");
8467 if ($sorted_order) {
8468 return trim($uname[
"lastname"] .
", " . $uname[
"firstname"]) . $suffix;
8470 return trim($uname[
"firstname"] .
" " . $uname[
"lastname"]) . $suffix;
8484 if ($this->getNrOfTries() == 1) {
8485 return $this->
lng->txt(
"tst_start_test");
8487 $active_pass = self::_getPass($active_id);
8488 $res = $this->getNrOfResultsForPass($active_id, $active_pass);
8490 if ($active_pass == 0) {
8491 return $this->
lng->txt(
"tst_start_test");
8493 return $this->
lng->txt(
"tst_start_new_test_pass");
8496 return $this->
lng->txt(
"tst_resume_test");
8505 public function getAvailableDefaults(): array
8515 $result =
$ilDB->queryF(
8516 "SELECT * FROM tst_test_defaults WHERE user_fi = %s ORDER BY name ASC",
8520 $defaults = array();
8521 while ($row =
$ilDB->fetchAssoc($result)) {
8522 $defaults[$row[
"test_defaults_id"]] = $row;
8536 return self::_getTestDefaults($test_defaults_id);
8544 $result =
$ilDB->queryF(
8545 "SELECT * FROM tst_test_defaults WHERE test_defaults_id = %s",
8547 array($test_defaults_id)
8549 if ($result->numRows() == 1) {
8550 $row =
$ilDB->fetchAssoc($result);
8567 $affectedRows =
$ilDB->manipulateF(
8568 "DELETE FROM tst_test_defaults WHERE test_defaults_id = %s",
8570 array($test_default_id)
8585 $testsettings = array(
8586 "TitleOutput" => $this->getTitleOutput(),
8587 "PassScoring" => $this->getPassScoring(),
8588 "IntroEnabled" => $this->isIntroductionEnabled(),
8589 "Introduction" => $this->getIntroduction(),
8590 "FinalStatement" => $this->getFinalStatement(),
8591 "ShowInfo" => $this->getShowInfo(),
8592 "ForceJS" => $this->getForceJS(),
8593 "CustomStyle" => $this->getCustomStyle(),
8594 "ShowFinalStatement" => $this->getShowFinalStatement(),
8595 "SequenceSettings" => $this->getSequenceSettings(),
8596 "ScoreReporting" => $this->getScoreReporting(),
8597 "ScoreCutting" => $this->getScoreCutting(),
8598 'SpecificAnswerFeedback' => $this->getSpecificAnswerFeedback(),
8599 'PrintBsWithRes' => (
int) $this->isBestSolutionPrintedWithResult(),
8600 "InstantFeedbackSolution" => $this->getInstantFeedbackSolution(),
8601 "AnswerFeedback" => $this->getAnswerFeedback(),
8602 "AnswerFeedbackPoints" => $this->getAnswerFeedbackPoints(),
8603 "ResultsPresentation" => $this->getResultsPresentation(),
8604 "Anonymity" => $this->getAnonymity(),
8605 "ShowCancel" => $this->getShowCancel(),
8606 "ShowMarker" => $this->getShowMarker(),
8607 "ReportingDate" => $this->getReportingDate(),
8608 "NrOfTries" => $this->getNrOfTries(),
8609 'BlockAfterPassed' => (
int) $this->isBlockPassesAfterPassedEnabled(),
8610 "Shuffle" => $this->getShuffleQuestions(),
8611 "Kiosk" => $this->getKiosk(),
8612 "UsePreviousAnswers" => $this->getUsePreviousAnswers(),
8613 "ProcessingTime" => $this->getProcessingTime(),
8614 "EnableProcessingTime" => $this->getEnableProcessingTime(),
8615 "ResetProcessingTime" => $this->getResetProcessingTime(),
8616 "StartingTimeEnabled" => $this->isStartingTimeEnabled(),
8617 "StartingTime" => $this->getStartingTime(),
8618 "EndingTimeEnabled" => $this->isEndingTimeEnabled(),
8619 "EndingTime" => $this->getEndingTime(),
8620 "ECTSOutput" => $this->getECTSOutput(),
8621 "ECTSFX" => $this->getECTSFX(),
8622 "ECTSGrades" => $this->getECTSGrades(),
8623 "questionSetType" => $this->getQuestionSetType(),
8624 "CountSystem" => $this->getCountSystem(),
8625 "mailnotification" => $this->getMailNotification(),
8626 "mailnottype" => $this->getMailNotificationType(),
8627 "exportsettings" => $this->getExportSettings(),
8628 "ListOfQuestionsSettings" => $this->getListOfQuestionsSettings(),
8629 'obligations_enabled' => (
int) $this->areObligationsEnabled(),
8630 'offer_question_hints' => (
int) $this->isOfferingQuestionHintsEnabled(),
8631 'pass_deletion_allowed' => (
int) $this->isPassDeletionAllowed(),
8632 'enable_examview' => $this->getEnableExamview(),
8633 'show_examview_html' => $this->getShowExamviewHtml(),
8634 'show_examview_pdf' => $this->getShowExamviewPdf(),
8635 'char_selector_availability' => $this->getCharSelectorAvailability(),
8636 'char_selector_definition' => $this->getCharSelectorDefinition(),
8637 'skill_service' => (
int) $this->isSkillServiceEnabled(),
8638 'result_tax_filters' => $this->getResultFilterTaxIds(),
8639 'show_grading_status' => (
int) $this->isShowGradingStatusEnabled(),
8640 'show_grading_mark' => (
int) $this->isShowGradingMarkEnabled(),
8642 'follow_qst_answer_fixation' => $this->isFollowupQuestionAnswerFixationEnabled(),
8643 'inst_fb_answer_fixation' => $this->isInstantFeedbackAnswerFixationEnabled(),
8644 'force_inst_fb' => $this->isForceInstantFeedbackEnabled(),
8645 'redirection_mode' => $this->getRedirectionMode(),
8646 'redirection_url' => $this->getRedirectionUrl(),
8647 'sign_submission' => $this->getSignSubmission(),
8648 'autosave' => (
int) $this->getAutosave(),
8649 'autosave_ival' => $this->getAutosaveIval(),
8650 'examid_in_test_pass' => (
int) $this->isShowExamIdInTestPassEnabled(),
8651 'examid_in_test_res' => (
int) $this->isShowExamIdInTestResultsEnabled(),
8653 'enable_archiving' => (
int) $this->getEnableArchiving(),
8654 'password_enabled' => (
int) $this->isPasswordEnabled(),
8655 'password' => (
string) $this->getPassword(),
8656 'fixed_participants' => $this->getFixedParticipants(),
8657 'limit_users_enabled' => $this->isLimitUsersEnabled(),
8658 'allowedusers' => $this->getAllowedUsers(),
8659 'alloweduserstimegap' => $this->getAllowedUsersTimeGap(),
8660 'activation_limited' => $this->isActivationLimited(),
8661 'activation_start_time' => $this->getActivationStartingTime(),
8662 'activation_end_time' => $this->getActivationEndingTime(),
8663 'activation_visibility' => $this->getActivationVisibility(),
8664 'highscore_enabled' => $this->getHighscoreEnabled(),
8665 'highscore_anon' => $this->getHighscoreAnon(),
8666 'highscore_achieved_ts' => $this->getHighscoreAchievedTS(),
8667 'highscore_score' => $this->getHighscoreScore(),
8668 'highscore_percentage' => $this->getHighscorePercentage(),
8669 'highscore_hints' => $this->getHighscoreHints(),
8670 'highscore_wtime' => $this->getHighscoreWTime(),
8671 'highscore_own_table' => $this->getHighscoreOwnTable(),
8672 'highscore_top_table' => $this->getHighscoreTopTable(),
8673 'highscore_top_num' => $this->getHighscoreTopNum(),
8674 'use_previous_answers' => (
string) $this->getUsePreviousAnswers(),
8675 'pass_waiting' => $this->getPassWaiting()
8678 $next_id =
$ilDB->nextId(
'tst_test_defaults');
8680 'tst_test_defaults',
8682 'test_defaults_id' => array(
'integer', $next_id),
8683 'name' => array(
'text', $a_name),
8684 'user_fi' => array(
'integer',
$ilUser->getId()),
8685 'defaults' => array(
'clob', serialize($testsettings)),
8686 'marks' => array(
'clob', serialize($this->mark_schema)),
8687 'tstamp' => array(
'integer', time())
8701 $testsettings = unserialize($test_defaults[
"defaults"]);
8702 $this->mark_schema = unserialize($test_defaults[
"marks"]);
8704 if (array_key_exists(
'TitleOutput', $testsettings)) {
8705 $this->setTitleOutput($testsettings[
'TitleOutput']);
8708 if (array_key_exists(
'IntroEnabled', $testsettings)) {
8709 $this->setIntroductionEnabled($testsettings[
'IntroEnabled']);
8712 if (array_key_exists(
'Introduction', $testsettings)) {
8713 $this->setIntroduction($testsettings[
'Introduction'] ??
'');
8716 if (array_key_exists(
'FinalStatement', $testsettings)) {
8717 $this->setFinalStatement($testsettings[
'FinalStatement'] ??
'');
8720 if (array_key_exists(
'ShowInfo', $testsettings)) {
8721 $this->setShowInfo($testsettings[
'ShowInfo']);
8724 if (array_key_exists(
'ForceJS', $testsettings)) {
8725 $this->setForceJS($testsettings[
'ForceJS']);
8728 if (array_key_exists(
'CustomStyle', $testsettings)) {
8729 $this->setCustomStyle($testsettings[
'CustomStyle']);
8732 if (array_key_exists(
'ShowFinalStatement', $testsettings)) {
8733 $this->setShowFinalStatement($testsettings[
'ShowFinalStatement']);
8736 if (array_key_exists(
'SequenceSettings', $testsettings)) {
8737 $this->setSequenceSettings($testsettings[
'SequenceSettings']);
8740 if (array_key_exists(
'SpecificAnswerFeedback', $testsettings)) {
8741 $this->setSpecificAnswerFeedback($testsettings[
'SpecificAnswerFeedback']);
8744 if (array_key_exists(
'InstantFeedbackSolution', $testsettings)) {
8745 $this->setInstantFeedbackSolution($testsettings[
'InstantFeedbackSolution']);
8748 if (array_key_exists(
'AnswerFeedback', $testsettings)) {
8749 $this->setAnswerFeedback($testsettings[
'AnswerFeedback']);
8752 if (array_key_exists(
'AnswerFeedbackPoints', $testsettings)) {
8753 $this->setAnswerFeedbackPoints($testsettings[
'AnswerFeedbackPoints']);
8756 if (array_key_exists(
'Anonymity', $testsettings)) {
8757 $this->setAnonymity($testsettings[
'Anonymity']);
8760 if (array_key_exists(
'ShowCancel', $testsettings)) {
8761 $this->setShowCancel($testsettings[
'ShowCancel']);
8764 if (array_key_exists(
'Shuffle', $testsettings)) {
8765 $this->setShuffleQuestions($testsettings[
'Shuffle']);
8768 if (array_key_exists(
'ShowMarker', $testsettings)) {
8769 $this->setShowMarker($testsettings[
'ShowMarker']);
8772 if (array_key_exists(
'ReportingDate', $testsettings)) {
8773 $this->setReportingDate($testsettings[
'ReportingDate']);
8776 if (array_key_exists(
'NrOfTries', $testsettings)) {
8777 $this->setNrOfTries($testsettings[
'NrOfTries']);
8780 if (array_key_exists(
'BlockAfterPassed', $testsettings)) {
8781 $this->setBlockPassesAfterPassedEnabled($testsettings[
'BlockAfterPassed']);
8784 if (array_key_exists(
'UsePreviousAnswers', $testsettings)) {
8785 $this->setUsePreviousAnswers($testsettings[
'UsePreviousAnswers']);
8788 if (array_key_exists(
'redirection_mode', $testsettings)) {
8789 $this->setRedirectionMode($testsettings[
'redirection_mode']);
8792 if (array_key_exists(
'redirection_url', $testsettings)) {
8793 $this->setRedirectionUrl($testsettings[
'redirection_url']);
8796 if (array_key_exists(
'ProcessingTime', $testsettings)) {
8797 $this->setProcessingTime($testsettings[
'ProcessingTime']);
8800 if (array_key_exists(
'ResetProcessingTime', $testsettings)) {
8801 $this->setResetProcessingTime($testsettings[
'ResetProcessingTime']);
8804 if (array_key_exists(
'EnableProcessingTime', $testsettings)) {
8805 $this->setEnableProcessingTime($testsettings[
'EnableProcessingTime']);
8808 if (array_key_exists(
'StartingTimeEnabled', $testsettings)) {
8809 $this->setStartingTimeEnabled($testsettings[
'StartingTimeEnabled']);
8812 if (array_key_exists(
'StartingTime', $testsettings)) {
8813 $this->setStartingTime($testsettings[
'StartingTime']);
8816 if (array_key_exists(
'Kiosk', $testsettings)) {
8817 $this->setKiosk($testsettings[
'Kiosk']);
8820 if (array_key_exists(
'EndingTimeEnabled', $testsettings)) {
8821 $this->setEndingTimeEnabled($testsettings[
'EndingTimeEnabled']);
8824 if (array_key_exists(
'EndingTime', $testsettings)) {
8825 $this->setEndingTime($testsettings[
'EndingTime']);
8828 if (array_key_exists(
'ECTSOutput', $testsettings)) {
8829 $this->setECTSOutput($testsettings[
'ECTSOutput']);
8832 if (array_key_exists(
'ECTSFX', $testsettings)) {
8833 $this->setECTSFX($testsettings[
'ECTSFX']);
8836 if (array_key_exists(
'ECTSGrades', $testsettings)) {
8837 $this->setECTSGrades($testsettings[
'ECTSGrades']);
8840 if (isset($testsettings[
"isRandomTest"])) {
8841 if ($testsettings[
"isRandomTest"]) {
8842 $this->setQuestionSetType(self::QUESTION_SET_TYPE_RANDOM);
8844 $this->setQuestionSetType(self::QUESTION_SET_TYPE_FIXED);
8846 } elseif (isset($testsettings[
"questionSetType"])) {
8847 $this->setQuestionSetType($testsettings[
"questionSetType"]);
8850 if (array_key_exists(
'mailnotification', $testsettings)) {
8851 $this->setMailNotification($testsettings[
'mailnotification']);
8854 if (array_key_exists(
'mailnottype', $testsettings)) {
8855 $this->setMailNotificationType($testsettings[
'mailnottype']);
8858 if (array_key_exists(
'exportsettings', $testsettings)) {
8859 $this->setExportSettings($testsettings[
'exportsettings']);
8862 if (array_key_exists(
'ListOfQuestionsSettings', $testsettings)) {
8863 $this->setListOfQuestionsSettings($testsettings[
'ListOfQuestionsSettings']);
8866 if (array_key_exists(
'obligations_enabled', $testsettings)) {
8867 $this->setObligationsEnabled($testsettings[
'obligations_enabled']);
8870 if (array_key_exists(
'offer_question_hints', $testsettings)) {
8871 $this->setOfferingQuestionHintsEnabled($testsettings[
'offer_question_hints']);
8874 if (isset($testsettings[
'examid_in_kiosk'])) {
8875 $this->setShowExamIdInTestPassEnabled($testsettings[
'examid_in_kiosk']);
8877 $this->setShowExamIdInTestPassEnabled($testsettings[
'examid_in_test_pass']);
8880 if (array_key_exists(
'enable_examview', $testsettings)) {
8881 $this->setEnableExamview($testsettings[
'enable_examview']);
8884 if (array_key_exists(
'show_examview_html', $testsettings)) {
8885 $this->setShowExamviewHtml($testsettings[
'show_examview_html']);
8888 if (array_key_exists(
'show_examview_pdf', $testsettings)) {
8889 $this->setShowExamviewPdf($testsettings[
'show_examview_pdf']);
8892 if (array_key_exists(
'enable_archiving', $testsettings)) {
8893 $this->setEnableArchiving($testsettings[
'enable_archiving']);
8896 if (array_key_exists(
'sign_submission', $testsettings)) {
8897 $this->setSignSubmission($testsettings[
'sign_submission']);
8900 if (array_key_exists(
'char_selector_availability', $testsettings)) {
8901 $this->setCharSelectorAvailability($testsettings[
'char_selector_availability']);
8904 if (array_key_exists(
'char_selector_definition', $testsettings)) {
8905 $this->setCharSelectorDefinition($testsettings[
'char_selector_definition']);
8908 if (array_key_exists(
'skill_service', $testsettings)) {
8909 $this->setSkillServiceEnabled((
bool) $testsettings[
'skill_service']);
8912 if (array_key_exists(
'show_grading_status', $testsettings)) {
8913 $this->setShowGradingStatusEnabled((
bool) $testsettings[
'show_grading_status']);
8916 if (array_key_exists(
'show_grading_mark', $testsettings)) {
8917 $this->setShowGradingMarkEnabled((
bool) $testsettings[
'show_grading_mark']);
8920 if (array_key_exists(
'follow_qst_answer_fixation', $testsettings)) {
8921 $this->setFollowupQuestionAnswerFixationEnabled($testsettings[
'follow_qst_answer_fixation']);
8924 if (array_key_exists(
'inst_fb_answer_fixation', $testsettings)) {
8925 $this->setInstantFeedbackAnswerFixationEnabled($testsettings[
'inst_fb_answer_fixation']);
8928 if (array_key_exists(
'force_inst_fb', $testsettings)) {
8929 $this->setForceInstantFeedbackEnabled($testsettings[
'force_inst_fb']);
8932 if (array_key_exists(
'redirection_mode', $testsettings)) {
8933 $this->setRedirectionMode($testsettings[
'redirection_mode']);
8936 if (array_key_exists(
'redirection_url', $testsettings)) {
8937 $this->setRedirectionUrl($testsettings[
'redirection_url']);
8940 if (array_key_exists(
'autosave', $testsettings)) {
8941 $this->setAutosave($testsettings[
'autosave']);
8944 if (array_key_exists(
'autosave_ival', $testsettings)) {
8945 $this->setAutosaveIval($testsettings[
'autosave_ival']);
8948 if (array_key_exists(
'password_enabled', $testsettings)) {
8949 $this->setPasswordEnabled($testsettings[
'password_enabled']);
8952 if (array_key_exists(
'password', $testsettings)) {
8953 $this->setPassword($testsettings[
'password']);
8956 if (array_key_exists(
'fixed_participants', $testsettings)) {
8957 $this->setFixedParticipants($testsettings[
'fixed_participants']);
8960 if (array_key_exists(
'limit_users_enabled', $testsettings)) {
8961 $this->setLimitUsersEnabled($testsettings[
'limit_users_enabled']);
8964 if (array_key_exists(
'allowedusers', $testsettings)) {
8965 $this->setAllowedUsers($testsettings[
'allowedusers']);
8968 if (array_key_exists(
'alloweduserstimegap', $testsettings)) {
8969 $this->setAllowedUsersTimeGap($testsettings[
'alloweduserstimegap']);
8972 if (array_key_exists(
'use_previous_answers', $testsettings)) {
8973 $this->setUsePreviousAnswers($testsettings[
'use_previous_answers']);
8976 if (array_key_exists(
'activation_limited', $testsettings)) {
8977 $this->setActivationLimited($testsettings[
'activation_limited']);
8980 if (array_key_exists(
'activation_start_time', $testsettings)) {
8981 $this->setActivationStartingTime($testsettings[
'activation_start_time']);
8984 if (array_key_exists(
'activation_end_time', $testsettings)) {
8985 $this->setActivationEndingTime($testsettings[
'activation_end_time']);
8988 if (array_key_exists(
'activation_visibility', $testsettings)) {
8989 $this->setActivationVisibility($testsettings[
'activation_visibility']);
8992 if (array_key_exists(
'pass_waiting', $testsettings)) {
8993 $this->setPassWaiting($testsettings[
'pass_waiting']);
8997 $exam_id_in_results =
false;
8998 if (array_key_exists(
'show_exam_id', $testsettings)) {
8999 $exam_id_in_results = (bool) $testsettings[
'show_exam_id'];
9000 } elseif (array_key_exists(
'examid_in_test_res', $testsettings)) {
9001 $exam_id_in_results = (bool) $testsettings[
'examid_in_test_res'];
9005 ->withScoringSettings(
9007 ->withPassScoring((
bool) $testsettings[
"PassScoring"])
9008 ->withScoreCutting((
bool) $testsettings[
'ScoreCutting'])
9009 ->withCountSystem((
bool) $testsettings[
"CountSystem"])
9011 ->withResultSummarySettings(
9013 ->withPassDeletionAllowed($testsettings[
'pass_deletion_allowed'])
9015 ->withResultDetailsSettings(
9017 ->withPrintBestSolutionWithResult((
bool) $testsettings[
'PrintBsWithRes'])
9018 ->withShowExamIdInTestResults($exam_id_in_results)
9019 ->withTaxonomyFilterIds((array) $testsettings[
'result_tax_filters'])
9021 ->withGamificationSettings(
9023 ->withHighscoreEnabled($testsettings[
'highscore_enabled'])
9024 ->withHighscoreAnon($testsettings[
'highscore_anon'])
9025 ->withHighscoreAchievedTS($testsettings[
'highscore_achieved_ts'])
9026 ->withHighscoreScore($testsettings[
'highscore_score'])
9027 ->withHighscorePercentage($testsettings[
'highscore_percentage'])
9028 ->withHighscoreHints($testsettings[
'highscore_hints'])
9029 ->withHighscoreWTime($testsettings[
'highscore_wtime'])
9030 ->withHighscoreOwnTable($testsettings[
'highscore_own_table'])
9031 ->withHighscoreTopTable($testsettings[
'highscore_top_table'])
9032 ->withHighscoreTopNum($testsettings[
'highscore_top_num'])
9035 $this->getScoreSettingsRepository()->store(
$settings);
9050 if (extension_loaded(
"tidy")) {
9053 "output-xml" =>
true,
9054 "numeric-entities" =>
true
9057 $tidy->parseString($print_output,
$config,
'utf8');
9058 $tidy->cleanRepair();
9059 $print_output = tidy_get_output($tidy);
9060 $print_output = preg_replace(
"/^.*?(<html)/",
"\\1", $print_output);
9062 $print_output = str_replace(
" ",
" ", $print_output);
9063 $print_output = str_replace(
"⊗",
"X", $print_output);
9065 $xsl = file_get_contents(
"./Modules/Test/xml/question2fo.xsl");
9070 'font-family="Helvetica, unifont"',
9071 'font-family="' .
$DIC[
'ilSetting']->
get(
'rpc_pdf_font',
'Helvetica, unifont') .
'"',
9075 $args = array(
'/_xml' => $print_output,
'/_xsl' => $xsl );
9078 $output = xslt_process($xh,
"arg:/_xml",
"arg:/_xsl",
null, $args,
$params);
9092 $content = preg_replace(
"/href=\".*?\"/",
"", $content);
9093 $printbody =
new ilTemplate(
"tpl.il_as_tst_print_body.html",
true,
true,
"Modules/Test");
9095 $printbody->setVariable(
"ADM_CONTENT", $content);
9096 $printbody->setCurrentBlock(
"css_file");
9098 $printbody->parseCurrentBlock();
9099 $printoutput = $printbody->get();
9100 $html = str_replace(
"href=\"./",
"href=\"" . ILIAS_HTTP_PATH .
"/", $printoutput);
9101 $html = preg_replace(
"/<div id=\"dontprint\">.*?<\\/div>/ims",
"", $html);
9102 if (extension_loaded(
"tidy")) {
9105 "output-xml" =>
true,
9106 "numeric-entities" =>
true
9109 $tidy->parseString($html,
$config,
'utf8');
9110 $tidy->cleanRepair();
9111 $html = tidy_get_output($tidy);
9112 $html = preg_replace(
"/^.*?(<html)/",
"\\1", $html);
9114 $html = str_replace(
" ",
" ", $html);
9115 $html = str_replace(
"⊗",
"X", $html);
9117 $html = preg_replace(
"/src=\".\\//ims",
"src=\"" . ILIAS_HTTP_PATH .
"/", $html);
9118 $this->deliverPDFfromFO($this->processPrintoutput2FO($html), $title);
9129 $ilLog =
$DIC[
'ilLog'];
9132 $fp = fopen($fo_file,
"w");
9138 $filename = (strlen($title)) ? $title : $this->getTitle();
9141 $pdf_base64->scalar,
9146 }
catch (Exception
$e) {
9147 $ilLog->write(__METHOD__ .
': ' .
$e->getMessage());
9164 $row = self::getSingleManualFeedback((
int) $active_id, (
int) $question_id, (
int) $pass);
9167 $feedback = $row[
'feedback'] ??
'';
9179 $result =
$ilDB->queryF(
9180 "SELECT * FROM tst_manual_fb WHERE active_fi = %s AND question_fi = %s AND pass = %s",
9181 [
'integer',
'integer',
'integer'],
9182 [$active_id, $question_id, $pass]
9185 if (
$ilDB->numRows($result) === 1) {
9186 $row =
$ilDB->fetchAssoc($result);
9188 } elseif (
$ilDB->numRows($result) > 1) {
9189 $DIC->logger()->root()->warning(
9190 "WARNING: Multiple feedback entries on tst_manual_fb for " .
9191 "active_fi = $active_id , question_fi = $question_id and pass = $pass"
9210 $feedback = array();
9211 $result =
$ilDB->queryF(
9212 "SELECT * FROM tst_manual_fb WHERE question_fi = %s",
9217 while ($row =
$ilDB->fetchAssoc($result)) {
9218 $active = $row[
'active_fi'];
9219 $pass = $row[
'pass'];
9220 $question = $row[
'question_fi'];
9224 $feedback[$active][$pass][$question] = $row;
9235 bool $finalized =
false,
9236 bool $is_single_feedback =
false
9240 $feedback_old = self::getSingleManualFeedback($active_id, $question_id, $pass);
9242 $finalized_record = (
int) ($feedback_old[
'finalized_evaluation'] ?? 0);
9243 if ($finalized_record === 0 || ($is_single_feedback && $finalized_record === 1)) {
9244 $DIC->database()->manipulateF(
9245 "DELETE FROM tst_manual_fb WHERE active_fi = %s AND question_fi = %s AND pass = %s",
9246 [
'integer',
'integer',
'integer'],
9247 [$active_id, $question_id, $pass]
9250 $this->insertManualFeedback($active_id, $question_id, $pass, $feedback, $finalized, $feedback_old);
9253 $this->logManualFeedback($active_id, $question_id, $feedback);
9272 $next_id =
$ilDB->nextId(
'tst_manual_fb');
9274 $finalized_time = time();
9277 'manual_feedback_id' => [
'integer', $next_id],
9278 'active_fi' => [
'integer', $active_id],
9279 'question_fi' => [
'integer', $question_id],
9280 'pass' => [
'integer', $pass],
9282 'tstamp' => [
'integer', time()]
9285 if ($feedback_old !== [] && (
int) $feedback_old[
'finalized_evaluation'] === 1) {
9286 $user = $feedback_old[
'finalized_by_usr_id'];
9287 $finalized_time = $feedback_old[
'finalized_tstamp'];
9290 if ($finalized ===
false) {
9291 $update_default[
'finalized_evaluation'] = [
'integer', 0];
9292 $update_default[
'finalized_by_usr_id'] = [
'integer', 0];
9293 $update_default[
'finalized_tstamp'] = [
'integer', 0];
9294 } elseif ($finalized ===
true) {
9295 $update_default[
'finalized_evaluation'] = [
'integer', 1];
9296 $update_default[
'finalized_by_usr_id'] = [
'integer', $user];
9297 $update_default[
'finalized_tstamp'] = [
'integer', $finalized_time];
9300 $ilDB->insert(
'tst_manual_fb', $update_default);
9343 $this->testSequence =
new ilTestSequence($active_id, $pass, $this->isRandomTest());
9353 $this->test_id = $a_id;
9367 if (count($participants)) {
9368 foreach ($participants as $active_id => $user_rec) {
9370 $reached_points = 0;
9373 foreach ($this->questions as $value) {
9375 if (is_object($question)) {
9376 $max_points += $question->getMaximumPoints();
9377 $reached_points += $question->getReachedPoints($active_id, $pass);
9378 if ($max_points > 0) {
9379 $percentvalue = $reached_points / $max_points;
9380 if ($percentvalue < 0) {
9381 $percentvalue = 0.0;
9386 if ($this->getAnonymity()) {
9387 $user_rec[
'firstname'] =
"";
9388 $user_rec[
'lastname'] = $this->
lng->txt(
"anonymous");
9391 "user_id" => $user_rec[
'usr_id'],
9392 "matriculation" => $user_rec[
'matriculation'],
9393 "lastname" => $user_rec[
'lastname'],
9394 "firstname" => $user_rec[
'firstname'],
9395 "login" => $user_rec[
'login'],
9396 "question_id" => $question->getId(),
9397 "question_title" => $question->getTitle(),
9398 "reached_points" => $reached_points,
9399 "max_points" => $max_points,
9400 "passed" => $user_rec[
'passed'] ?
'1' :
'0',
9418 $result =
$ilDB->queryF(
9419 "SELECT t.obj_fi obj_id FROM tst_test_question q, tst_tests t WHERE q.test_fi = t.test_id AND q.question_fi = %s",
9423 $rec =
$ilDB->fetchAssoc($result);
9424 return $rec[
"obj_id"] ??
null;
9436 $component_repository =
$DIC[
'component.repository'];
9438 if (!$component_repository->getComponentByTypeAndName(
9441 )->getPluginSlotById(
'qst')->hasPluginName($a_pname)) {
9445 return $component_repository
9446 ->getComponentByTypeAndName(
9450 ->getPluginSlotById(
9463 $result =
$ilDB->queryF(
9464 "SELECT passed FROM tst_result_cache WHERE active_fi = %s",
9468 if ($result->numRows()) {
9469 $row =
$ilDB->fetchAssoc($result);
9470 return $row[
'passed'];
9473 $result_array = &$this->getTestResult($active_id, $counted_pass);
9474 return $result_array[
"test"][
"passed"];
9481 public function getParticipantsForTestAndQuestion($test_id, $question_id): array
9488 SELECT tst_test_result.active_fi, tst_test_result.question_fi, tst_test_result.pass
9489 FROM tst_test_result
9490 INNER JOIN tst_active ON tst_active.active_id = tst_test_result.active_fi AND tst_active.test_fi = %s
9491 INNER JOIN qpl_questions ON qpl_questions.question_id = tst_test_result.question_fi
9492 LEFT JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
9493 WHERE tst_test_result.question_fi = %s
9494 ORDER BY usr_data.lastname ASC, usr_data.firstname ASC
9497 $result =
$ilDB->queryF(
9499 array(
'integer',
'integer'),
9500 array($test_id, $question_id)
9502 $foundusers = array();
9504 while ($row =
$ilDB->fetchAssoc($result)) {
9505 if ($this->getAccessFilteredParticipantList() && !$this->getAccessFilteredParticipantList()->isActiveIdInList($row[
"active_fi"])) {
9509 if (!array_key_exists($row[
"active_fi"], $foundusers)) {
9510 $foundusers[$row[
"active_fi"]] = array();
9512 array_push($foundusers[$row[
"active_fi"]], array(
"pass" => $row[
"pass"],
"qid" => $row[
"question_fi"]));
9524 $data = &$this->getCompleteEvaluationData();
9525 $foundParticipants =
$data->getParticipants();
9526 $results = array(
"overview" => array(),
"questions" => array());
9527 if (count($foundParticipants)) {
9528 $results[
"overview"][$this->
lng->txt(
"tst_eval_total_persons")] = count($foundParticipants);
9529 $total_finished =
$data->getTotalFinishedParticipants();
9530 $results[
"overview"][$this->
lng->txt(
"tst_eval_total_finished")] = $total_finished;
9531 $average_time = $this->evalTotalStartedAverageTime(
$data->getParticipantIds());
9532 $diff_seconds = $average_time;
9533 $diff_hours = floor($diff_seconds / 3600);
9534 $diff_seconds -= $diff_hours * 3600;
9535 $diff_minutes = floor($diff_seconds / 60);
9536 $diff_seconds -= $diff_minutes * 60;
9537 $results[
"overview"][$this->
lng->txt(
"tst_eval_total_finished_average_time")] = sprintf(
"%02d:%02d:%02d", $diff_hours, $diff_minutes, $diff_seconds);
9539 $total_passed_reached = 0;
9540 $total_passed_max = 0;
9541 $total_passed_time = 0;
9542 foreach ($foundParticipants as $userdata) {
9543 if ($userdata->getPassed()) {
9545 $total_passed_reached += $userdata->getReached();
9546 $total_passed_max += $userdata->getMaxpoints();
9547 $total_passed_time += $userdata->getTimeOfWork();
9550 $average_passed_reached = $total_passed ? $total_passed_reached / $total_passed : 0;
9551 $average_passed_max = $total_passed ? $total_passed_max / $total_passed : 0;
9552 $average_passed_time = $total_passed ? $total_passed_time / $total_passed : 0;
9553 $results[
"overview"][$this->
lng->txt(
"tst_eval_total_passed")] = $total_passed;
9554 $results[
"overview"][$this->
lng->txt(
"tst_eval_total_passed_average_points")] = sprintf(
"%2.2f", $average_passed_reached) .
" " . strtolower($this->
lng->txt(
"of")) .
" " . sprintf(
"%2.2f", $average_passed_max);
9555 $average_time = $average_passed_time;
9556 $diff_seconds = $average_time;
9557 $diff_hours = floor($diff_seconds / 3600);
9558 $diff_seconds -= $diff_hours * 3600;
9559 $diff_minutes = floor($diff_seconds / 60);
9560 $diff_seconds -= $diff_minutes * 60;
9561 $results[
"overview"][$this->
lng->txt(
"tst_eval_total_passed_average_time")] = sprintf(
"%02d:%02d:%02d", $diff_hours, $diff_minutes, $diff_seconds);
9564 foreach (
$data->getQuestionTitles() as $question_id => $question_title) {
9568 foreach ($foundParticipants as $userdata) {
9569 for (
$i = 0;
$i <= $userdata->getLastPass();
$i++) {
9570 if (is_object($userdata->getPass(
$i))) {
9571 $question = $userdata->getPass(
$i)->getAnsweredQuestionByQuestionId($question_id);
9572 if (is_array($question)) {
9574 $reached += $question[
"reached"];
9575 $max += $question[
"points"];
9580 $percent = $max ? $reached / $max * 100.0 : 0;
9581 $results[
"questions"][$question_id] = array(
9583 sprintf(
"%.2f", $answered ? $reached / $answered : 0) .
" " . strtolower($this->
lng->txt(
"of")) .
" " . sprintf(
"%.2f", $answered ? $max / $answered : 0),
9584 sprintf(
"%.2f", $percent) .
"%",
9586 sprintf(
"%.2f", $answered ? $reached / $answered : 0),
9587 sprintf(
"%.2f", $answered ? $max / $answered : 0),
9600 $test_exp = $expFactory->getExporter(
'xml');
9601 return $test_exp->buildExportFile();
9606 return $this->mailnotification;
9611 $this->mailnotification = $a_notification;
9617 $owner_id = $this->getOwner();
9619 $mail->sendSimpleNotification($owner_id, $this->getTitle(), $usr_data);
9630 return $table_gui->getSelectedColumns();
9636 $owner_id = $this->getOwner();
9640 $participantList->initializeFromDbRows($this->getTestParticipants());
9643 $exportObj = $expFactory->getExporter(
'results');
9644 $exportObj->setForcedAccessFilteredParticipantList($participantList);
9645 $file = $exportObj->exportToExcel($deliver =
false,
'active_id', $active_id, $passedonly =
false);
9647 $fd->copyAttachmentFile($file,
"result_" . $active_id .
".xlsx");
9648 $file_names[] =
"result_" . $active_id .
".xlsx";
9650 $mail->sendAdvancedNotification($owner_id, $this->getTitle(), $usr_data, $file_names);
9652 if (count($file_names)) {
9653 $fd->unlinkFiles($file_names);
9666 FROM tst_result_cache
9667 WHERE active_fi = %s
9670 $result =
$ilDB->queryF(
9676 if (!$result->numRows()) {
9681 FROM tst_result_cache
9682 WHERE active_fi = %s
9685 $result =
$ilDB->queryF(
9692 $row =
$ilDB->fetchAssoc($result);
9699 if ($this->mailnottype == 1) {
9700 return $this->mailnottype;
9709 $this->mailnottype = 1;
9711 $this->mailnottype = 0;
9717 return $this->getScoreSettings()->getResultDetailsSettings()->getExportSettings();
9723 $this->exportsettings = $a_settings;
9725 $this->exportsettings = 0;
9731 return $this->getScoreSettings()->getResultDetailsSettings()->getExportSettingsSingleChoiceShort();
9737 $this->exportsettings = $this->exportsettings | 1;
9739 if ($this->getExportSettingsSingleChoiceShort()) {
9740 $this->exportsettings = $this->exportsettings ^ 1;
9747 return $this->enabled_view_mode;
9752 $this->enabled_view_mode = $mode;
9757 $this->template_id = (
int) $template_id;
9762 return $this->template_id;
9768 $this->getSpecificAnswerFeedback() || $this->getGenericAnswerFeedback() ||
9769 $this->getAnswerFeedbackPoints() || $this->getInstantFeedbackSolution()
9777 if ($this->getSpecificAnswerFeedback()) {
9778 $values[] =
'instant_feedback_specific';
9780 if ($this->getGenericAnswerFeedback()) {
9781 $values[] =
'instant_feedback_generic';
9783 if ($this->getAnswerFeedbackPoints()) {
9784 $values[] =
'instant_feedback_points';
9786 if ($this->getInstantFeedbackSolution()) {
9787 $values[] =
'instant_feedback_solution';
9795 if (is_array($options)) {
9796 $this->setGenericAnswerFeedback(in_array(
'instant_feedback_generic', $options) ? 1 : 0);
9797 $this->setSpecificAnswerFeedback(in_array(
'instant_feedback_specific', $options) ? 1 : 0);
9798 $this->setAnswerFeedbackPoints(in_array(
'instant_feedback_points', $options) ? 1 : 0);
9799 $this->setInstantFeedbackSolution(in_array(
'instant_feedback_solution', $options) ? 1 : 0);
9801 $this->setGenericAnswerFeedback(0);
9802 $this->setSpecificAnswerFeedback(0);
9803 $this->setAnswerFeedbackPoints(0);
9804 $this->setInstantFeedbackSolution(0);
9814 $tree =
$DIC[
'tree'];
9816 $component_repository =
$DIC[
'component.repository'];
9819 $questionSetConfig = $qscFactory->getQuestionSetConfig();
9822 $reindexedSequencePositionMap = $questionSetConfig->reindexQuestionOrdering();
9824 $this->loadQuestions();
9826 return $reindexedSequencePositionMap;
9838 foreach ($orders as
$id => $position) {
9842 isset($obligations[
$id]) && $obligations[
$id] ? 1 : 0
9846 UPDATE tst_test_question
9849 WHERE question_fi = %s
9854 array(
'integer',
'integer',
'integer'),
9855 array(
$i, $obligatory,
$id)
9859 $this->loadQuestions();
9866 if ($question_before) {
9867 $query =
'SELECT sequence, test_fi FROM tst_test_question WHERE question_fi = %s';
9868 $types = array(
'integer');
9869 $values = array($question_before);
9873 if (!$question_before || ($rset && !($row =
$ilDB->fetchAssoc($rset)))) {
9876 'test_fi' => $this->getTestId(),
9880 $update =
'UPDATE tst_test_question SET sequence = sequence + 1 WHERE sequence > %s AND test_fi = %s';
9881 $types = array(
'integer',
'integer');
9882 $values = array($row[
'sequence'], $row[
'test_fi']);
9885 $update =
'UPDATE tst_test_question SET sequence = %s WHERE question_fi = %s';
9886 $types = array(
'integer',
'integer');
9887 $values = array($row[
'sequence'] + 1, $question_to_move);
9890 $this->reindexFixedQuestionOrdering();
9898 $questions = $this->getQuestionTitlesAndIndexes();
9900 $IN_questions =
$ilDB->in(
'q1.question_id', array_keys($questions),
false,
'integer');
9903 SELECT count(q1.question_id) cnt
9905 FROM qpl_questions q1
9907 INNER JOIN qpl_questions q2
9908 ON q2.question_id = q1.original_id
9911 AND q1.obj_fi = q2.obj_fi
9916 $row =
$ilDB->fetchAssoc($rset);
9918 return $row[
'cnt'] > 0;
9932 $result =
$ilDB->queryF(
9933 "SELECT test_fi,MAX(pass) AS pass FROM tst_active" .
9934 " JOIN tst_pass_result ON (tst_pass_result.active_fi = tst_active.active_id)" .
9935 " WHERE user_fi=%s" .
9936 " GROUP BY test_fi",
9937 array(
'integer',
'integer'),
9938 array($a_user_id, 1)
9941 while ($row =
$ilDB->fetchAssoc($result)) {
9942 $obj_id = self::_getObjectIDFromTestID($row[
"test_fi"]);
9943 $all[$obj_id] = (bool) $row[
"pass"];
9949 return $this->questions;
9954 return $this->online;
9959 $this->online = (bool) $a_online;
9967 return $this->oldOnlineStatus;
9972 $this->oldOnlineStatus = $oldOnlineStatus;
9977 return $this->getScoreSettings()->getResultDetailsSettings()->getPrintBestSolutionWithResult();
9987 return $this->offeringQuestionHintsEnabled ?:
false;
9997 $this->offeringQuestionHintsEnabled = (bool) $offeringQuestionHintsEnabled;
10002 $this->activation_visibility = (bool) $a_value;
10007 return $this->activation_visibility;
10012 return $this->activation_limited;
10017 $this->activation_limited = (bool) $a_value;
10023 return $this->getScoreSettings()->getGamificationSettings()->getHighscoreEnabled();
10037 return $this->getScoreSettings()->getGamificationSettings()->getHighscoreAnon();
10050 return $this->getAnonymity() == 1 || $this->getHighscoreAnon();
10058 return $this->getScoreSettings()->getGamificationSettings()->getHighscoreAchievedTS();
10066 return $this->getScoreSettings()->getGamificationSettings()->getHighscoreScore();
10074 return $this->getScoreSettings()->getGamificationSettings()->getHighscorePercentage();
10082 return $this->getScoreSettings()->getGamificationSettings()->getHighscoreHints();
10090 return $this->getScoreSettings()->getGamificationSettings()->getHighscoreWTime();
10098 return $this->getScoreSettings()->getGamificationSettings()->getHighscoreOwnTable();
10106 return $this->getScoreSettings()->getGamificationSettings()->getHighscoreTopTable();
10115 return $this->getScoreSettings()->getGamificationSettings()->getHighscoreTopNum();
10120 return $this->getScoreSettings()->getGamificationSettings()->getHighScoreMode();
10126 switch ($specific_answer_feedback) {
10128 $this->specific_answer_feedback = 1;
10131 $this->specific_answer_feedback = 0;
10138 switch ($this->specific_answer_feedback) {
10153 $this->obligationsEnabled = (bool) $obligationsEnabled;
10163 return (
bool) $this->obligationsEnabled;
10180 $obligationPossible = call_user_func(array($classConcreteQuestion,
'isObligationPossible'), $questionId);
10182 return $obligationPossible;
10196 $rset =
$ilDB->queryF(
'SELECT obligatory FROM tst_test_question WHERE question_fi = %s', array(
'integer'), array($question_id));
10198 if ($row =
$ilDB->fetchAssoc($rset)) {
10199 return (
bool) $row[
'obligatory'];
10222 $rset =
$ilDB->queryF(
10223 'SELECT obligations_answered FROM tst_pass_result WHERE active_fi = %s AND pass = %s',
10224 array(
'integer',
'integer'),
10225 array($active_id, $pass)
10228 if ($row =
$ilDB->fetchAssoc($rset)) {
10229 return (
bool) $row[
'obligations_answered'];
10232 return !self::hasObligations($test_id);
10248 $rset =
$ilDB->queryF(
10249 'SELECT count(*) cnt FROM tst_test_question WHERE test_fi = %s AND obligatory = 1',
10254 $row =
$ilDB->fetchAssoc($rset);
10256 return (
bool) $row[
'cnt'] > 0;
10261 $this->autosave = $autosave;
10266 return $this->autosave;
10271 $this->autosave_ival = $autosave_ival;
10276 return $this->autosave_ival;
10281 return $this->getScoreSettings()->getResultSummarySettings()->getPassDeletionAllowed();
10284 #region Examview / PDF Examview
10290 $this->show_examview_html = $show_examview_html;
10298 return $this->show_examview_html;
10306 $this->show_examview_pdf = $show_examview_pdf;
10314 return $this->show_examview_pdf;
10322 $this->enable_examview = $enable_examview;
10330 return $this->enable_examview;
10337 $this->activation_starting_time = $starting_time;
10342 $this->activation_ending_time = $ending_time;
10347 return (strlen($this->activation_starting_time)) ? $this->activation_starting_time :
null;
10352 return (strlen($this->activation_ending_time)) ? $this->activation_ending_time :
null;
10367 $result =
$ilDB->queryF(
10368 "SELECT tst_times.active_fi, tst_times.started FROM tst_times, tst_active WHERE tst_times.active_fi = tst_active.active_id AND tst_active.test_fi = %s ORDER BY tst_times.tstamp DESC",
10370 array($this->getTestId())
10372 while ($row =
$ilDB->fetchAssoc($result)) {
10373 $times[$row[
'active_fi']] = $row[
'started'];
10384 $result =
$ilDB->queryF(
10385 "SELECT tst_addtime.active_fi, tst_addtime.additionaltime FROM tst_addtime, tst_active WHERE tst_addtime.active_fi = tst_active.active_id AND tst_active.test_fi = %s",
10387 array($this->getTestId())
10389 while ($row =
$ilDB->fetchAssoc($result)) {
10390 $times[$row[
'active_fi']] = $row[
'additionaltime'];
10400 $result =
$ilDB->queryF(
10401 "SELECT additionaltime FROM tst_addtime WHERE active_fi = %s",
10405 if ($result->numRows() > 0) {
10406 $row =
$ilDB->fetchAssoc($result);
10407 return $row[
'additionaltime'];
10416 $participantData->setParticipantAccessFilter(
10421 $participantData->setActiveIdsFilter(array($active_id));
10424 $participantData->load($this->getTestId());
10426 foreach ($participantData->getActiveIds() as $active_fi) {
10427 $result = $this->db->queryF(
10428 "SELECT active_fi FROM tst_addtime WHERE active_fi = %s",
10433 if ($result->numRows() > 0) {
10434 $this->db->manipulateF(
10435 "DELETE FROM tst_addtime WHERE active_fi = %s",
10441 $this->db->manipulateF(
10442 "UPDATE tst_active SET tries = %s, submitted = %s, submittimestamp = %s WHERE active_id = %s",
10443 array(
'integer',
'integer',
'timestamp',
'integer'),
10444 array(0, 0,
null, $active_fi)
10447 $this->db->manipulateF(
10448 "INSERT INTO tst_addtime (active_fi, additionaltime, tstamp) VALUES (%s, %s, %s)",
10449 array(
'integer',
'integer',
'integer'),
10450 array($active_fi, $minutes, time())
10466 $this->enable_archiving = $enable_archiving;
10475 return $this->enable_archiving;
10478 public function getMaxPassOfTest():
int
10487 SELECT MAX(tst_pass_result.pass) + 1 max_res
10488 FROM tst_pass_result
10489 INNER JOIN tst_active ON tst_active.active_id = tst_pass_result.active_fi
10490 WHERE test_fi = ' .
$ilDB->quote($this->getTestId(),
'integer') .
'
10494 return (
int)
$data[
'max_res'];
10502 $exam_id_query =
'SELECT exam_id FROM tst_pass_result WHERE active_fi = %s AND pass = %s';
10503 $exam_id_result =
$ilDB->queryF($exam_id_query, array(
'integer',
'integer' ), array( $active_id, $pass ));
10504 if (
$ilDB->numRows($exam_id_result) == 1) {
10505 $exam_id_row =
$ilDB->fetchAssoc($exam_id_result);
10507 if ($exam_id_row[
'exam_id'] !=
null) {
10508 return $exam_id_row[
'exam_id'];
10515 public static function buildExamId($active_id, $pass, $test_obj_id =
null): string
10520 $inst_id =
$ilSetting->get(
'inst_id',
null);
10522 if ($test_obj_id ===
null) {
10523 $obj_id = self::_getObjectIDFromActiveID($active_id);
10525 $obj_id = $test_obj_id;
10528 $examId =
'I' . $inst_id .
'_T' . $obj_id .
'_A' . $active_id .
'_P' . $pass;
10535 $this->show_exam_id_in_test_pass_enabled = $show_exam_id_in_test_pass_enabled;
10540 return $this->show_exam_id_in_test_pass_enabled;
10548 return $this->getScoreSettings()->getResultDetailsSettings()->getShowExamIdInTestResults();
10556 $this->sign_submission = $sign_submission;
10564 return $this->sign_submission;
10569 $this->char_selector_availability = (
int) $availability;
10577 return (
int) $this->char_selector_availability;
10585 $this->char_selector_definition = $definition;
10593 return $this->char_selector_definition;
10604 $this->questionSetType = $questionSetType;
10614 return $this->questionSetType;
10629 $query =
"SELECT question_set_type FROM tst_tests WHERE obj_fi = %s";
10633 $questionSetType =
null;
10635 while ($row =
$ilDB->fetchAssoc(
$res)) {
10636 $questionSetType = $row[
'question_set_type'];
10639 return $questionSetType;
10649 return $this->getQuestionSetType() == self::QUESTION_SET_TYPE_FIXED;
10659 return $this->getQuestionSetType() == self::QUESTION_SET_TYPE_RANDOM;
10669 return $this->getQuestionSetType() == self::QUESTION_SET_TYPE_DYNAMIC;
10681 return self::lookupQuestionSetType($a_obj_id) == self::QUESTION_SET_TYPE_RANDOM;
10686 switch ($questionSetType) {
10688 return $lng->txt(
'tst_question_set_type_fixed');
10691 return $lng->txt(
'tst_question_set_type_random');
10694 throw new ilTestException(
'invalid question set type value given: ' . $questionSetType);
10699 if ($this->participantDataExist ===
null) {
10700 $this->participantDataExist = (bool) $this->evalTotalPersons();
10703 return $this->participantDataExist;
10709 $scoring->setPreserveManualScores($preserve_manscoring);
10710 $scoring->recalculateSolutions();
10722 INNER JOIN tst_tests
10723 ON test_id = test_fi
10731 while ($row =
$ilDB->fetchAssoc(
$res)) {
10732 $objIds[] = (
int) $row[
'obj_fi'];
10740 $this->skillServiceEnabled = $skillServiceEnabled;
10745 return $this->skillServiceEnabled;
10750 if ($this->getTestId() != -1) {
10751 return $this->getScoreSettings()->getResultDetailsSettings()->getTaxonomyFilterIds();
10769 if (!$this->isSkillServiceEnabled()) {
10773 if (!self::isSkillManagementGloballyActivated()) {
10780 private static $isSkillManagementGloballyActivated =
null;
10784 if (self::$isSkillManagementGloballyActivated ===
null) {
10787 self::$isSkillManagementGloballyActivated = $skmgSet->isActivated();
10790 return self::$isSkillManagementGloballyActivated;
10795 $this->showGradingStatusEnabled = $showGradingStatusEnabled;
10800 return $this->showGradingStatusEnabled;
10805 $this->showGradingMarkEnabled = $showGradingMarkEnabled;
10811 return $this->showGradingMarkEnabled;
10816 $this->followupQuestionAnswerFixationEnabled = $followupQuestionAnswerFixationEnabled;
10821 return $this->followupQuestionAnswerFixationEnabled;
10826 $this->instantFeedbackAnswerFixationEnabled = $instantFeedbackAnswerFixationEnabled;
10831 return $this->instantFeedbackAnswerFixationEnabled;
10836 return $this->forceInstantFeedbackEnabled;
10844 $this->forceInstantFeedbackEnabled = $forceInstantFeedbackEnabled;
10853 $component_repository =
$DIC[
'component.repository'];
10859 $activeId = $testOBJ->getActiveIdOfUser($userId);
10865 $testSession = $testSessionFactory->getSession($activeId);
10866 $testSequence = $testSequenceFactory->getSequenceByActiveIdAndPass($activeId, $testSession->getPass());
10867 $testSequence->loadFromDb();
10870 if ($a_force_new_run) {
10871 if ($testSequence->hasSequence()) {
10872 $testSession->increasePass();
10874 $testSession->setLastSequence(0);
10875 $testSession->saveToDb();
10886 $component_repository =
$DIC[
'component.repository'];
10893 $activeId = $testOBJ->getActiveIdOfUser($userId);
10897 $testSessionFactory->reset();
10901 $testSession = $testSessionFactory->getSession($activeId);
10902 $testSequence = $testSequenceFactory->getSequenceByActiveIdAndPass($activeId, $testSession->getPass());
10903 $testSequence->loadFromDb();
10905 return $testSequence->hasSequence();
10913 return $this->testFinalBroken;
10921 $this->testFinalBroken = $testFinalBroken;
10930 SELECT COUNT(test_question_id) cnt
10931 FROM tst_test_question
10936 $questRes =
$ilDB->queryF(
$query, array(
'integer'), array($this->getTestId()));
10938 $row =
$ilDB->fetchAssoc($questRes);
10939 $questCount = $row[
'cnt'];
10941 if ($this->getShuffleQuestions()) {
10944 FROM tst_active tac
10945 INNER JOIN tst_sequence tseq
10946 ON tseq.active_fi = tac.active_id
10947 WHERE tac.test_fi = %s
10950 $partRes =
$ilDB->queryF(
10953 array($this->getTestId())
10956 while ($row =
$ilDB->fetchAssoc($partRes)) {
10957 $sequence = @unserialize($row[
'sequence']);
10960 $sequence = array();
10963 $sequence = array_filter($sequence,
function ($value) use ($questCount) {
10964 return $value <= $questCount;
10967 $num_seq = count($sequence);
10968 if ($questCount > $num_seq) {
10969 $diff = $questCount - $num_seq;
10970 for (
$i = 1;
$i <= $diff;
$i++) {
10971 $sequence[$num_seq +
$i - 1] = $num_seq +
$i;
10975 $new_sequence = serialize($sequence);
10977 $ilDB->update(
'tst_sequence', array(
10978 'sequence' => array(
'clob', $new_sequence)
10980 'active_fi' => array(
'integer', $row[
'active_fi']),
10981 'pass' => array(
'integer', $row[
'pass'])
10985 $new_sequence = serialize($questCount > 0 ? range(1, $questCount) : array());
10989 FROM tst_active tac
10990 INNER JOIN tst_sequence tseq
10991 ON tseq.active_fi = tac.active_id
10992 WHERE tac.test_fi = %s
10995 $part_rest =
$ilDB->queryF(
10998 array($this->getTestId())
11001 while ($row =
$ilDB->fetchAssoc($part_rest)) {
11002 $ilDB->update(
'tst_sequence', array(
11003 'sequence' => array(
'clob', $new_sequence)
11005 'active_fi' => array(
'integer', $row[
'active_fi']),
11006 'pass' => array(
'integer', $row[
'pass'])
11022 if (!$this->score_settings) {
11023 $this->score_settings = $this->getScoreSettingsRepository()
11024 ->getFor($this->getTestId());
11026 return $this->score_settings;
11031 if (!$this->score_settings_repo) {
11034 return $this->score_settings_repo;
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
raiseError(string $a_msg, int $a_err_obj)
wrapper for downward compability
const NEWS_NOTICE
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Abstract basic class which is to be extended by the concrete assessment question type classes.
static _isWorkedThrough(int $active_id, int $question_id, int $pass)
Returns true if the question was worked through in the given pass Worked through means that the user ...
static _getQuestionType(int $question_id)
static _getSolutionMaxPass(int $question_id, int $active_id)
Returns the maximum pass a users question solution.
static _getOriginalId(int $question_id)
static _includeClass(string $question_type, int $gui=0)
static _getSuggestedSolutionOutput(int $question_id)
static getFeedbackClassNameByQuestionType(string $questionType)
static _getQuestionTitle(int $question_id)
static instantiateQuestion(int $question_id)
static _updateTestResultCache(int $active_id, ilAssQuestionProcessLocker $processLocker=null)
@TODO Move this to a proper place.
static deleteRequestsByActiveIds($activeIds)
Deletes all hint requests relating to a testactive included in given active ids.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static completeMissingPluginName($questionTypeData)
static _getInstance(int $a_copy_id)
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
@classDescription Date and time handling
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class handles all operations on files (attachments) in directory ilias_data/mail.
static getASCIIFilename(string $a_filename)
static makeDir(string $a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
static ilTempnam(?string $a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
static delDir(string $a_dir, bool $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static getDataDir()
get data directory (outside webspace)
static removeTrailingPathSeparators(string $path)
static getInstanceByType(string $type)
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)
loadLanguageModule(string $a_module)
Load language module.
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
A news item can be created by different sources.
static getFirstNewsIdForContext(int $a_context_obj_id, string $a_context_obj_type, int $a_context_sub_obj_id=0, string $a_context_sub_obj_type="")
Get first new id of news set related to a certain context.
static deleteNewsOfContext(int $a_context_obj_id, string $a_context_obj_type, int $a_context_sub_obj_id=0, string $a_context_sub_obj_type="")
Delete all news of a context.
static _addLog( $user_id, $object_id, $logtext, $question_id=0, $original_id=0, $test_only=false, $test_ref_id=0)
Add an assessment log entry.
static _getManualScoring()
Retrieve the manual scoring settings.
static _enabledAssessmentLogging()
static _getAvailableQuestionpools($use_object_id=false, $equal_points=false, $could_be_offline=false, $showPath=false, $with_questioncount=false, $permission="read", $usr_id="")
Returns the available question pools for the active user.
static _getParticipantData($active_id)
Retrieves a participant name from active id.
static _isPassed($user_id, $a_obj_id)
Returns TRUE if the user with the user id $user_id passed the test with the object id $a_obj_id.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getResultSummarySettings()
getGamificationSettings()
getResultDetailsSettings()
withGamificationSettings(ilObjTestSettingsGamification $settings)
static _getECTSGrade($points_passed, $reached_points, $max_points, $a, $b, $c, $d, $e, $fx)
{Returns the ECTS grade for a number of reached points.string The ECTS grade short description}
getResetProcessingTime()
Returns wheather the processing time should be reset or not.
_buildName($is_anonymous, $user_id, $firstname, $lastname, $title)
Builds a user name for the output depending on test type and existence of the user.
getActivationEndingTime()
static _getResultPass($active_id)
Retrieves the pass number that should be counted for a given user.
setAnswerFeedback($answer_feedback=0)
Sets the generic feedback for the test @deprecate Use setGenericAnswerFeedback instead.
exportXMLPageObjects(&$a_xml_writer, $a_inst, &$expLog)
export page objects to xml (see ilias_co.dtd)
static _getObjectIDFromActiveID($active_id)
Returns the ILIAS test object id for a given active id.
getProcessingTimeAsMinutes()
static _instanciateQuestion($question_id)
Creates an instance of a question with a given question id.
getUserData($ids)
Returns a data of all users specified by id list.
getEstimatedWorkingTime()
Returns the estimated working time for the test calculated from the working time of the contained que...
setShowInfo($a_info=1)
Set whether the complete information page is shown or the required data only.
const QUESTION_SET_TYPE_DYNAMIC
getTestId()
Gets the database id of the additional test data.
endingTimeReached()
Returns true if the ending time of a test is reached An ending time is not available for self assessm...
setClientIP($user_id, $client_ip)
setAllowedUsersTimeGap($a_allowed_users_time_gap)
getQuestionSetType()
getter for question set type
setTestId($a_id)
Sets the test ID.
getShowKioskModeParticipant()
Returns the status of the kiosk mode participant.
setKiosk($kiosk=0)
Sets the kiosk mode for the test.
getQuestionTitle($title, $nr=null)
Returns the title of a test question and checks if the title output is allowed.
getHighscoreWTime()
Gets if the column with the workingtime should be shown.
getHighscoreOwnTable()
Gets if the own rankings table should be shown.
getAnsweredQuestionCount($active_id, $pass=null)
Retrieves the number of answered questions for a given user in a given test.
ILIAS Test InternalRequestService $testrequest
getShowKioskModeTitle()
Returns the status of the kiosk mode title.
getHighscoreTopTable()
Gets, if the top-rankings table should be shown.
getCountSystem()
Gets the count system for the calculation of points.
isShowExamIdInTestPassEnabled()
setPostponingEnabled($postponingEnabled)
setInstantFeedbackSolution($instant_feedback=0)
Sets the instant feedback for the solution.
canShowSolutionPrintview($user_id=null)
getEnableProcessingTime()
Returns the state of the processing time (enabled/disabled)
setShowKioskModeParticipant($a_participant=false)
Set to true, if the participant's name should be shown in kiosk mode.
getListOfQuestionsStart()
Returns if the list of questions should be presented as the first page of the test.
& getExistingQuestions($pass=null)
Get the id's of the questions which are already part of the test.
saveToDb(bool $properties_only=false)
getActiveParticipantList()
static _getTestIDFromObjectID($object_id)
Returns the ILIAS test id for a given object id.
pcArrayShuffle($array)
Shuffles the values of a given array.
getShowSolutionListOwnAnswers($user_id=null)
_getTitleOutput($active_id)
Returns the value of the title_output status.
isAnyInstantFeedbackOptionEnabled()
$char_selector_availability
isComplete(ilTestQuestionSetConfig $testQuestionSetConfig)
canShowTestResults(ilTestSession $testSession)
getInstantFeedbackSolution()
Returns 1 if the correct solution will be shown after answering a question.
setFixedParticipants($a_value=1)
Sets the fixed participants status.
getStartingTimeOfUser($active_id, $pass=null)
Returns the unix timestamp of the time a user started a test.
_getLastAccess($active_id)
getStartTestLabel($active_id)
Returns the "Start the Test" label for the Info page.
static _getTestDefaults($test_defaults_id)
setOnline($a_online=true)
& getParticipants()
Returns all persons who started the test.
setProcessingTime($processing_time="00:00:00")
Sets the processing time for the test.
int $reset_processing_time
getDetailedTestResults($participants)
returns all test results for all participants
setAllowedUsers($a_allowed_users)
isNrOfTriesReached($tries)
returns if number of tries are reached
reindexFixedQuestionOrdering()
static getTestObjIdsWithActiveForUserId($userId)
setKioskMode($a_kiosk=false)
Sets the kiosk mode for the test.
setTemplate($template_id)
setShowExamviewPdf($show_examview_pdf)
setShowExamIdInTestPassEnabled($show_exam_id_in_test_pass_enabled)
getScoreSettingsRepository()
isPreviousSolutionReuseEnabled($active_id)
inviteUser($user_id, $client_ip="")
Invites a user to a test.
static _getCountSystem($active_id)
Gets the count system for the calculation of points.
setAuthor(string $author="")
Sets the authors name of the ilObjTest object.
evalTotalPersonsArray($name_sort_order="asc")
Returns all persons who started the test.
evalTotalStartedAverageTime($activeIdsFilter=null)
Returns the average processing time for all started tests.
setFollowupQuestionAnswerFixationEnabled($followupQuestionAnswerFixationEnabled)
getQuestiontext($question_id)
Returns the question text for a given question.
QTIMaterialToString($a_material)
Reads an QTI material tag an creates a text string.
const QUESTION_SET_TYPE_RANDOM
setOldOnlineStatus($oldOnlineStatus)
processPrintoutput2FO($print_output)
Convert a print output to XSL-FO.
sendSimpleNotification($active_id)
getXMLZip()
Get zipped xml file for test.
getShowSolutionListComparison()
static lookupExamId($active_id, $pass)
createExportDirectory()
creates data directory for export files (data_dir/tst_data/tst_<id>/export, depending on data directo...
bool $followupQuestionAnswerFixationEnabled
ilObjTestScoreSettings $score_settings
& getTestResult( $active_id, $pass=null, bool $ordered_sequence=false, bool $considerHiddenQuestions=true, bool $considerOptionalQuestions=true)
Calculates the results of a test for a given user and returns an array with all test results.
setShowGradingStatusEnabled($showGradingStatusEnabled)
static _getActiveIdOfUser($user_id="", $test_id="")
getFixedParticipants()
Returns the fixed participants status.
isBestSolutionPrintedWithResult()
_lookupRandomTestFromActiveId($active_id)
Returns the random status of a test with a given object id.
setPassword($a_password=null)
Sets the password for test access.
& createTestSequence($active_id, $pass, $shuffle)
createQuestionGUI($question_type, $question_id=-1)
Creates a question GUI instance of a given question type.
bool $show_exam_id_in_test_results_enabled
getProcessingTimeAsArray()
questionMoveDown($question_id)
Moves a question down in order.
setShowFinalStatement($show=0)
Sets whether the final statement should be shown or not.
bool $blockPassesAfterPassedEnabled
isMaxProcessingTimeReached(int $starting_time, int $active_id)
Returns whether the maximum processing time for a test is reached or not.
logAction($logtext="", $question_id="")
Logs an action into the Test&Assessment log.
$metadata
A reference to an IMS compatible matadata set.
getEvaluationAdditionalFields()
Gets additional user fields that should be shown in the user evaluation.
string $char_selector_definition
setEndingTimeEnabled($ending_time_enabled)
loadQuestions($active_id="", $pass=null)
Load the test question id's from the database.
& getCompleteEvaluationData($withStatistics=true, $filterby="", $filtertext="")
insertQuestion(ilTestQuestionSetConfig $testQuestionSetConfig, $question_id, $linkOnly=false)
Insert a question in the list of questions.
buildName($user_id, $firstname, $lastname, $title)
Builds a user name for the output depending on test type and existence of the user.
hasRandomQuestionsForPass(int $active_id, int $pass)
Checkes wheather a random test has already created questions for a given pass or not.
setRedirectionUrl($redirection_url=null)
hasQuestionsWithoutQuestionpool()
buildIso8601PeriodFromUnixtimeForExportCompatibility($unix_timestamp)
exportFileItems($target_dir, &$expLog)
export files of file itmes
removeQuestionFromSequences($questionId, $activeIds, ilTestReindexedSequencePositionMap $reindexedSequencePositionMap)
$mark_schema
Defines the mark schema ASS_MarkSchema ?
getImagePath()
Returns the image path for web accessable images of a test The image path is under the CLIENT_WEB_DIR...
getShowSolutionSignature()
Returns if the signature field should be shown in the test results.
getHighscoreAnon()
Gets if the highscores should be anonymized per setting.
exportXMLMediaObjects(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
export media objects to xml (see ilias_co.dtd)
getPassScoring()
Gets the pass scoring type.
setInstantFeedbackAnswerFixationEnabled($instantFeedbackAnswerFixationEnabled)
ScoreSettingsRepository $score_settings_repo
isShowGradingStatusEnabled()
setPasswordEnabled($passwordEnabled)
isHighscoreAnon()
Gets if the highscores should be displayed anonymized.
setOfferingQuestionHintsEnabled($offeringQuestionHintsEnabled)
sets offering question hints enabled/disabled
getShowSolutionAnswersOnly()
Returns if the full solution (including ILIAS content) should be presented to the solution or not.
isExecutable($testSession, $user_id, $allowPassIncrease=false)
Checks if the test is executable by the given user.
& getTestParticipants()
Returns a list of all participants in a test.
getStartingTime()
Returns the starting time of the test.
startingTimeReached()
Returns true if the starting time of a test is reached A starting time is not available for self asse...
bool $offeringQuestionHintsEnabled
setListOfQuestions($a_value=true)
Sets if the the list of questions should be presented to the user or not.
& getTotalPointsPassedArray()
Returns an array with the total points of all users who passed the test This array could be used for ...
getShowPassDetails()
Returns if the pass details should be shown when a test is not finished.
getQuestionSetTypeTranslation(ilLanguage $lng, $questionSetType)
& evalResultsOverview()
Creates an associated array with the results of all participants of a test.
getResultsPresentation()
Returns the combined results presentation value.
bool $show_exam_id_in_test_pass_enabled
static _lookupAuthor($obj_id)
Gets the authors name of the ilObjTest object.
saveCompleteStatus(ilTestQuestionSetConfig $testQuestionSetConfig)
getKioskMode()
Returns the kiosk mode.
getSequenceSettings()
SEQUENCE SETTING = POSTPONING ENABLED !!
static allObligationsAnswered($test_id, $active_id, $pass)
checks wether all questions marked as obligatory were answered within the test pass with given testId...
getShowSolutionFeedback()
Returns if the feedback should be presented to the solution or not.
static _getPassScoring($active_id)
Gets the pass scoring type.
getTimeExtensionsOfParticipants()
getActivationStartingTime()
setShowSolutionPrintview(int $a_printview=1)
Sets if the the solution printview should be presented to the user or not.
static _getQuestionCountAndPointsForPassOfParticipant($active_id, $pass)
const QUESTION_SET_TYPE_FIXED
duplicateQuestionForTest($question_id)
Takes a question and creates a copy of the question for use in the test.
setRedirectionMode($redirection_mode=0)
hasSingleChoiceQuestions()
setMailNotification($a_notification)
isActiveTestSubmitted($user_id=null)
returns if the active for user_id has been submitted
setQuestionSetType($questionSetType)
setter for question set type
setReportingDate($reporting_date)
Sets the reporting date of the ilObjTest object when the score reporting is available.
static lookupQuestionSetType($objId)
lookup-er for question set type
evalStatistical($active_id)
Returns the statistical evaluation of the test for a specified user.
setCharSelectorDefinition($definition='')
getKiosk()
Returns the kiosk mode.
getResultsForActiveId($active_id)
getShowSolutionDetails()
Returns if the solution details should be presented to the user or not.
setQuestionOrderAndObligations($orders, $obligations)
isTestQuestion($questionId)
$activation_starting_time
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
getAuthor()
Gets the authors name of the ilObjTest object.
$forceInstantFeedbackEnabled
getAnswerFeedbackPoints()
Returns 1 if answer specific feedback as reached points is activated.
setIntroductionEnabled($introductionEnabled)
getProcessingTimeInSeconds($active_id="")
Returns the processing time for the test in seconds.
saveManualFeedback(int $active_id, int $question_id, int $pass, ?string $feedback, bool $finalized=false, bool $is_single_feedback=false)
getFixedQuestionSetTotalPoints()
static lookupLastTestPassAccess($activeId, $passIndex)
inviteGroup($group_id)
Invites all users of a group to a test.
getScoreCutting()
Determines if the score of a question should be cut at 0 points or the score of the whole test.
getShowSolutionSuggested()
getHighscorePercentage()
Gets if the percentage column should be shown.
getQuestionCountWithoutReloading()
addDefaults($a_name)
Adds the defaults of this test to the test defaults.
prepareTextareaOutput($txt_output, $prepare_for_latex_output=false, $omitNl2BrWhenTextArea=false)
Prepares a string for a text area output in tests.
setListOfQuestionsEnd($a_value=true)
Sets if the the list of questions as the end page of the test.
getTestParticipantsForManualScoring($filter=null)
getHtmlQuestionContentPurifier()
setResetProcessingTime($reset=0)
Sets wheather the processing time should be reset or not.
moveQuestions($move_questions, $target_index, $insert_mode)
Move questions to another position.
static _getObjectIDFromTestID($test_id)
Returns the ILIAS test object id for a given test id.
setListOfQuestionsSettings($a_value=0)
Sets the settings for the list of questions options in the test properties This could contain one of ...
isSkillServiceToBeConsidered()
Returns whether this test must consider skills, usually by providing appropriate extensions in the us...
sendAdvancedNotification($active_id)
modifyExportIdentifier($a_tag, $a_param, $a_value)
Returns the installation id for a given identifier.
saveAuthorToMetadata(string $a_author="")
Saves an authors name into the lifecycle metadata if no lifecycle metadata exists This will only be c...
updateWorkingTime($times_id)
Update the working time of a test when a question is answered.
setActivationStartingTime($starting_time=null)
removeQuestion(int $question_id)
static isSkillManagementGloballyActivated()
getHighscoreHints()
Gets, if the column with the number of requested hints should be shown.
buildStatisticsAccessFilteredParticipantList()
$evaluation_data
Contains the evaluation data settings the tutor defines for the user.
getGenericAnswerFeedback()
Returns 1 if generic answer feedback is to be shown.
doCreateMetaData()
@inheritDoc
setObligationsEnabled($obligationsEnabled=true)
sets obligations enabled/disabled
setSkillServiceEnabled($skillServiceEnabled)
int $instant_verification
fromXML(ilQTIAssessment $assessment)
Receives parameters from a QTI parser and creates a valid ILIAS test object.
static _setImportDirectory($a_import_dir=null)
static _getMaxPass($active_id)
Retrieves the maximum pass of a given user for a given test in which the user answered at least one q...
isRandomTest()
Returns the fact wether this test is a random questions test or not.
getQuestionType($question_id)
Returns the question type of a question with a given id.
getShowSolutionPrintview()
Returns if the solution printview should be presented to the user or not.
exportXMLMetaData(&$a_xml_writer)
export content objects meta data to xml (see ilias_co.dtd)
static _getImportDirectory()
Get the import directory location of the test.
getShowInfo()
Gets whether the complete information page is shown or the required data only.
setActivationVisibility($a_value)
setQuestionSetSolved($value, $question_id, $user_id)
sets question solved state to value for given user_id
bool $skillServiceEnabled
isFixedTest()
Returns the fact wether this test is a fixed question set test or not.
getMarkSchema()
{ASS_MarkSchema}
& _getCompleteWorkingTimeOfParticipants($test_id)
Returns the complete working time in seconds for all test participants.
getTestDefaults($test_defaults_id)
Returns the test defaults for a given id.
deleteDefaults($test_default_id)
Deletes the defaults for a test.
getListOfQuestionsEnd()
Returns if the list of questions should be presented as the last page of the test.
getReportingDate()
Gets the reporting date of the ilObjTest object.
setForceJS($a_js=1)
Set whether JavaScript should be forced for tests.
isTestFinished($active_id)
returns if the active for user_id has been submitted
static _getBestPass($active_id)
Retrieves the best pass of a given user for a given test.
static getSingleManualFeedback(int $active_id, int $question_id, int $pass)
static _lookupRandomTest($a_obj_id)
Returns the fact wether the test with passed obj id is a random questions test or not.
getQuestionDataset($question_id)
Returns the dataset for a given question id.
getCharSelectorDefinition()
getTitleOutput()
Returns the value of the title_output status.
getAggregatedResultsData()
Returns the aggregated test results.
isDynamicTest()
Returns the fact wether this test is a dynamic question set test or not.
int $use_previous_answers
getAvailableQuestionpools($use_object_id=false, $equal_points=false, $could_be_offline=false, $show_path=false, $with_questioncount=false, $permission="read")
Returns the available question pools for the active user.
checkQuestionParent($questionId)
setInstantFeedbackOptionsByArray($options)
setFinalStatement(string $a_statement)
getHighscoreAchievedTS()
Returns if date and time of the scores achievement should be displayed.
setActivationEndingTime($ending_time=null)
getHighscoreTopNum(int $a_retval=10)
Gets the number of entries which are to be shown in the top-rankings table.
static getCompleteManualFeedback(int $question_id)
Retrieves the manual feedback for a question in a test.
& getQuestionTitlesAndIndexes()
Returns the titles of the test questions in question sequence.
getAllTestResults($participants, $prepareForCSV=true)
returns all test results for all participants
randomSelectQuestions(int $nr_of_questions, int $questionpool, $use_obj_id=0, $qpls="", $pass=null)
Returns a random selection of questions.
getListOfQuestions()
Returns if the list of questions should be presented to the user or not.
isHTML($a_text)
Checks if a given string contains HTML or not.
moveQuestionAfter($question_to_move, $question_before)
logManualFeedback($active_id, $question_id, $feedback)
Creates a log for the manual feedback.
setShuffleQuestions($a_shuffle)
Sets the status of the shuffle_questions variable.
getUsePreviousAnswers()
Returns if the previous answers should be shown for a learner.
setLimitUsersEnabled(bool $limitUsersEnabled)
& getWorkedQuestions($active_id, $pass=null)
Gets the id's of all questions a user already worked through.
bool $introductionEnabled
setForceInstantFeedbackEnabled($forceInstantFeedbackEnabled)
getAvailableQuestions($arrFilter, $completeonly=0)
Calculates the available questions for a test.
getListOfQuestionsSettings()
Returns the settings for the list of questions options in the test properties This could contain one ...
removeTestResultsByActiveIds($activeIds)
getCharSelectorAvailability()
startWorkingTime($active_id, $pass)
Write the initial entry for the tests working time to the database.
isFollowupQuestionAnswerFixationEnabled()
setBlockPassesAfterPassedEnabled($blockPassesAfterPassedEnabled)
setSpecificAnswerFeedback($specific_answer_feedback)
& processCSVRow($row, $quoteAll=false, $separator=";")
Processes an array as a CSV row and converts the array values to correct CSV values.
setMailNotificationType($a_type)
setTitleOutput($title_output=0)
Sets the status of the title output.
isOfferingQuestionHintsEnabled()
returns the fact wether offering hints is enabled or not
getCompleteWorkingTime($user_id)
Returns the complete working time in seconds a user worked on the test.
static buildExamId($active_id, $pass, $test_obj_id=null)
& getQuestionsOfTest($active_id)
Retrieves all the assigned questions for all test passes of a test participant.
getMailNotificationType()
setPassWaiting($pass_waiting)
array $resultFilterTaxIds
getForceJS()
Gets whether JavaScript should be forced for tests.
removeTestResults(ilTestParticipantData $participantData)
applyDefaults($test_defaults)
Applies given test defaults to this test.
disinviteUser($user_id)
Disinvites a user from a test.
setAnswerFeedbackPoints($answer_feedback_points=0)
Sets the answer specific feedback of reached points for the test.
getInstantFeedbackOptionsAsArray()
setStartingTimeEnabled($starting_time_enabled)
setIntroduction(string $introduction)
setECTSGrades(array $a_ects_grades)
__construct($a_id=0, bool $a_call_by_reference=true)
Constructor.
static lookupQuestionSetTypeByActiveId($active_id)
returns the question set type of test relating to passed active id
& getQuestionsOfPass($active_id, $pass)
Retrieves all the assigned questions for a test participant in a given test pass.
deliverPDFfromHTML($content, $title=null)
Delivers a PDF file from XHTML.
getImagePathWeb()
Returns the web image path for web accessable images of a test The image path is under the web access...
addQTIMaterial(&$a_xml_writer, $a_material='')
Creates a QTI material tag from a plain text or xhtml text.
static _getWorkingTimeOfParticipantForPass($active_id, $pass)
Returns the complete working time in seconds for a test participant.
static isQuestionObligationPossible($questionId)
checks wether the obligation for question with given id is possible or not
setActivationLimited($a_value)
isShowExamIdInTestResultsEnabled()
areObligationsEnabled()
returns the fact wether obligations are enabled or not
const DEFAULT_PROCESSING_TIME_MINUTES
static _createImportDirectory()
creates data directory for import files (data_dir/tst_data/tst_<id>/import, depending on data directo...
create()
note: title, description and type should be set when this function is called
getEndingTime()
Returns the ending time of the test.
static _getAvailableTests($use_object_id=false)
Returns the available tests for the active user.
float $ects_fx
Contains the percentage of maximum points a failed user needs to get the FX ECTS grade.
setShowKioskModeTitle($a_title=false)
Set to true, if the full test title should be shown in kiosk mode.
setShowGradingMarkEnabled($showGradingMarkEnabled)
getCompleteWorkingTimeOfParticipant($active_id)
Returns the complete working time in seconds for a test participant.
setStartingTime($starting_time=null)
Sets the starting time in database timestamp format for the test.
evalTotalPersons()
Returns the number of persons who started the test.
setEnableExamview($enable_examview)
setSignSubmission($sign_submission)
setEnableArchiving($enable_archiving)
& _evalResultsOverview($test_id)
Creates an associated array with the results of all participants of a test.
$ending_time_enabled
bool?
isInstantFeedbackAnswerFixationEnabled()
& getQuestionTitles()
Returns the titles of the test questions in question sequence.
getAllRTEContent()
Returns the content of all RTE enabled text areas in the test.
_getVisitTimeOfParticipant($test_id, $active_id)
Returns the first and last visit of a participant.
getSpecificAnswerFeedback()
getExportSettingsSingleChoiceShort()
setShowCancel($a_value=1)
Sets the cancel test button status.
bool $print_best_solution_with_result
removeQuestions(array $removeQuestionIds)
getMarkSchemaForeignId()
{int}
& getAllQuestions($pass=null)
Returns all questions of a test in test order.
static _getUserIdFromActiveId($active_id)
isPluginActive($a_pname)
Checks wheather or not a question plugin with a given name is active.
setAutosaveIval($autosave_ival)
getAnonymity()
Returns the anonymity status of the test.
deliverPDFfromFO($fo, $title=null)
Delivers a PDF file from a XSL-FO string.
static hasObligations($test_id)
returns the fact wether the test with given test id contains questions markes as obligatory or not
setTestFinalBroken($testFinalBroken)
toXML()
Returns a QTI xml representation of the test.
static lookupPassResultsUpdateTimestamp($active_id, $pass)
hasAnyTestResult(ilTestSession $testSession)
& evalResultsOverviewOfParticipant($active_id)
Creates an associated array with the results for a given participant of a test.
getShowCancel()
Returns wheather the cancel test button is shown or not.
setTmpCopyWizardCopyId(int $tmpCopyWizardCopyId)
getInvitedParticipantList()
setNrOfTries($nr_of_tries=0)
Sets the nr of tries for the test.
$participantDataExist
holds the fact wether participant data exists or not DO NOT USE TIS PROPERTY DRIRECTLY ALWAYS USE ilO...
getHighscoreScore()
Gets if the score column should be shown.
isBlockPassesAfterPassedEnabled()
setECTSOutput($a_ects_output)
& getInvitedUsers($user_id="", $order="login, lastname, firstname")
Returns a list of all invited users in a test.
setProcessingTimeByMinutes($minutes)
removeTestResultsFromSoapLpAdministration($userIds)
bool $instantFeedbackAnswerFixationEnabled
static _lookupFinishedUserTests($a_user_id)
Gather all finished tests for user.
static _getScoreCutting($active_id)
Determines if the score of a question should be cut at 0 points or the score of the whole test.
setListOfQuestionsStart($a_value=true)
Sets if the the list of questions as the start page of the test.
removeTestActives($activeIds)
getShowMarker()
Returns wheather the marker button is shown or not.
getImportMapping()
get array of (two) new created questions for import id
isSingleChoiceTestWithoutShuffle()
setCharSelectorAvailability($availability)
setAnonymity($a_value=0)
Sets the anonymity status of the test.
bool $showGradingMarkEnabled
insertManualFeedback(int $active_id, int $question_id, int $pass, ?string $feedback, bool $finalized, array $feedback_old)
checkMaximumAllowedUsers()
getShuffleQuestions()
Returns the status of the shuffle_questions variable.
setExportSettingsSingleChoiceShort($a_settings)
removeTestResultsByUserIds($userIds)
isNewRandomTest()
Checks wheather the test is a new random test (using tst_rnd_cpy) or an old one.
getListOfQuestionsDescription()
Returns TRUE if the list of questions should be presented with the question descriptions.
getECTSGrade($passed_array, $reached_points, $max_points)
{Returns the ECTS grade for a number of reached points.string The ECTS grade short description}
getActiveIdOfUser($user_id="", $anonymous_id="")
Gets the active id of a given user.
$accessFilteredParticipantList
checkMarks()
{boolean|string True or an error string which can be used for display purposes}
recalculateScores($preserve_manscoring=false)
setEnabledViewMode($mode)
static isParticipantsLastPassActive($testRefId, $userId)
getSecondsUntilEndingTime()
Returns the seconds left from the actual time until the ending time.
getNrOfTries()
Returns the nr of tries for the test.
setShowExamviewHtml($show_examview_html)
setGenericAnswerFeedback(int $generic_answer_feedback=0)
static _getSolvedQuestions($active_id, $question_fi=null)
get solved questions
static _lookupAnonymity($a_obj_id)
Returns the anonymity status of a test with a given object id.
setEnableProcessingTime($enable=0)
Sets the processing time enabled or disabled.
getActivationVisibility()
setUsePreviousAnswers($use_previous_answers=1)
Sets the status of the visibility of previous learner answers.
static getManualFeedback($active_id, $question_id, $pass)
Retrieves the feedback comment for a question in a test if it is finalized.
inviteRole($role_id)
Invites all users of a role to a test.
int $answer_feedback_points
getJavaScriptOutput()
Returns if Javascript should be chosen for drag & drop actions for the active user.
setListOfQuestionsDescription($a_value=true)
Sets the show_summary attribute to TRUE if the list of questions should be presented with the questio...
static isQuestionObligatory($question_id)
checks wether the question with given id is marked as obligatory or not
$testSequence
contains the test sequence data
evalTotalParticipantsArray($name_sort_order="asc")
Returns all participants who started the test.
getTextAnswer($active_id, $question_id, $pass=null)
Returns the text answer of a given user for a given question.
userLookupFullName($user_id, $overwrite_anonymity=false, $sorted_order=false, $suffix="")
Returns the full name of a test user according to the anonymity status.
getNrOfResultsForPass($active_id, $pass)
Calculates the number of user results for a specific test pass.
isShowGradingMarkEnabled()
setExportSettings($a_settings)
setEndingTime($ending_time=null)
Sets the ending time in database timestamp format for the test.
getStartingTimeOfParticipants()
Note, this function should only be used if absolutely necessary, since it perform joins on tables tha...
addExtraTime($active_id, $minutes)
getAccessFilteredParticipantList()
cleanupMediaobjectUsage()
Cleans up the media objects for all text fields in a test which are using an RTE field.
isTestFinishedToViewResults($active_id, $currentpass)
Returns true if an active user completed a test pass and did not start a new pass.
static ensureParticipantsLastActivePassFinished($testObjId, $userId, $a_force_new_run=false)
hasNrOfTriesRestriction()
returns if the numbers of tries have to be checked
static _lookupTestObjIdForQuestionId($a_q_id)
Get test Object ID for question ID.
setCustomStyle($a_customStyle=null)
Set the custom style.
bool $showGradingStatusEnabled
getVisitTimeOfParticipant($active_id)
Returns the first and last visit of a participant.
setAccessFilteredParticipantList($accessFilteredParticipantList)
getTitleFilenameCompliant()
returns the object title prepared to be used as a filename
int $specific_answer_feedback
getShowFinalStatement()
Returns whether the final statement should be shown or not.
questionMoveUp($question_id)
Moves a question up in order.
getProcessingTime()
Returns the processing time for the test.
setSequenceSettings($sequence_settings=0)
SEQUENCE SETTING = POSTPONING ENABLED !!
isForceInstantFeedbackEnabled()
$starting_time_enabled
bool?
& getCompleteWorkingTimeOfParticipants()
Returns the complete working time in seconds for all test participants.
getAnswerFeedback()
Returns 1 if generic answer feedback is activated.
$testSession
contains the test session data
exportPagesXML(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
export pages of test to xml (see ilias_co.dtd)
isScoreReportingEnabled()
$_customStyle
Name of a custom style sheet for the test string?
setShowMarker($a_value=1)
Sets the marker button status.
static _lookupName(int $a_user_id)
lookup user name
static _lookupClientIP(int $a_user_id)
Class ilObjectActivation.
const TIMINGS_DEACTIVATED
static getItem(int $ref_id)
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
static getInstance(int $obj_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupOwner(int $obj_id)
Lookup owner user ID for object ID.
static _prepareCloneSelection(array $ref_ids, string $new_type, bool $show_path=true)
Prepare copy wizard object selection.
setOfflineStatus(bool $status)
static _lookupObjId(int $ref_id)
static _lookupTitle(int $obj_id)
static _lookupDescription(int $obj_id)
static collectFileItems(ilPageObject $a_page, DOMDocument $a_domdoc)
Get all file items that are used within the page.
getPresentationMaterial()
static _cleanupMediaObjectUsage(string $a_text, string $a_usage_type, int $a_usage_id)
Synchronises appearances of media objects in $a_text with media object usage table.
static _replaceMediaObjectImageSrc(string $a_text, int $a_direction=0, string $nic='')
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
static factory(string $a_package, int $a_timeout=0)
Creates an ilRpcClient instance to our ilServer.
static get(string $a_var)
static clear(string $a_var)
static set(string $a_var, $a_val)
Set a value.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class provides mathematical functions for statistics.
special template class to simplify handling of ITX/PEAR
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getManageParticipantsUserFilter($refId)
static getAccessStatisticsUserFilter($refId)
isQuestionSetConfigured()
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static isManScoringDone($activeId)
reads the flag wether manscoring is done for the given test active or not from the global settings (s...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getStyleSheetLocation(string $mode="output", string $a_css_name="", string $a_css_location="")
get full style sheet file name (path inclusive) of current user
static insertInstIntoID(string $a_value)
inserts installation id into ILIAS id
static _getObjectsByOperations( $a_obj_type, string $a_operation, int $a_usr_id=0, int $limit=0)
Get all objects of a specific type and check access This function is not recursive,...
static deliverData(string $a_data, string $a_filename, string $mime="application/octet-stream")
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
for( $i=6;$i< 13;$i++) for($i=1; $i< 13; $i++) $d
const TEST_FIXED_SEQUENCE
Test constants.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Interface for html sanitizing functionality.
if(! $DIC->user() ->getId()||!ilLTIConsumerAccess::hasCustomProviderCreationAccess()) $params
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Refinery Factory $refinery
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
header include for all ilias files.