4 include_once
"./Modules/Test/classes/inc.AssessmentConstants.php";
27 self::IMG_MIME_TYPE_JPG => array(
'jpg',
'jpeg'),
28 self::IMG_MIME_TYPE_PNG => array(
'png'),
29 self::IMG_MIME_TYPE_GIF => array(
'gif')
33 self::IMG_MIME_TYPE_JPG => array(
'binary'),
34 self::IMG_MIME_TYPE_PNG => array(
'binary'),
35 self::IMG_MIME_TYPE_GIF => array(
'binary')
273 'image/jpeg' => array(
'jpg',
'jpeg'),
'image/png' => array(
'png'),
'image/gif' => array(
'gif')
297 $ilDB = $DIC[
'ilDB'];
304 $this->original_id = null;
310 if (!$this->author) {
311 $this->author = $this->
ilias->account->fullname;
314 if ($this->owner <= 0) {
315 $this->owner = $this->
ilias->account->id;
319 $this->suggested_solutions = array();
321 $this->nr_of_tries = 0;
323 $this->arrData = array();
326 $this->questionActionCmd =
'handleQuestionAction';
328 $this->lastChange = null;
330 require_once
'Services/Randomization/classes/class.ilArrayElementOrderKeeper.php';
343 return self::$forcePassResultsUpdateEnabled;
348 return (
bool) count(self::getAllowedFileExtensionsForMimeType($mimeType));
353 return current(explode(
';', $contentTypeString));
358 foreach (self::$allowedFileExtensionsByMimeType as $allowedMimeType => $extensions) {
359 $rexCharsets = implode(
'|', self::$allowedCharsetsByMimeType[$allowedMimeType]);
360 $rexMimeType = preg_quote($allowedMimeType,
'/');
362 $rex =
'/^' . $rexMimeType .
'(;(\s)*charset=(' . $rexCharsets .
'))*$/';
364 if (!preg_match($rex, $mimeType)) {
377 strtolower($fileExtension),
378 self::getAllowedFileExtensionsForMimeType($mimeType)
389 if (!isset(
$_POST[
'cmd']) || !isset(
$_POST[
'cmd'][$this->questionActionCmd])) {
393 if (!is_array(
$_POST[
'cmd'][$this->questionActionCmd]) || !count(
$_POST[
'cmd'][$this->questionActionCmd])) {
397 return key(
$_POST[
'cmd'][$this->questionActionCmd]);
406 if (!isset(
$_POST[$postSubmissionFieldname])) {
410 if (!is_array(
$_POST[$postSubmissionFieldname])) {
414 if (!count(
$_POST[$postSubmissionFieldname])) {
442 require_once
'Modules/Test/classes/class.ilObjTest.php';
453 $ilDB = $DIC[
'ilDB'];
456 "SELECT test_fi FROM tst_active WHERE active_id = %s",
462 return $row[
"test_fi"];
473 protected function log($active_id, $langVar)
486 $extensions = array();
488 foreach (self::$allowedImageMaterialFileExtensionsByMimeType as $mimeType => $mimeExtensions) {
489 $extensions = array_merge($extensions, $mimeExtensions);
491 return array_unique($extensions);
537 public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
539 include_once
"./Modules/TestQuestionPool/classes/import/qti12/class." . $this->
getQuestionType() .
"Import.php";
541 $import =
new $classname($this);
542 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
551 public function toXML($a_include_header =
true, $a_include_binary =
true, $a_shuffle =
false, $test_output =
false, $force_image_references =
false)
553 include_once
"./Modules/TestQuestionPool/classes/export/qti12/class." . $this->
getQuestionType() .
"Export.php";
555 $export =
new $classname($this);
556 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
580 $ilDB = $DIC[
'ilDB'];
583 "SELECT * FROM qpl_questions WHERE obj_fi = %s AND title = %s",
584 array(
'integer',
'text'),
585 array($questionpool_id,
$title)
587 return (
$result->numRows() > 0) ?
true :
false;
623 $this->test_id =
$id;
679 $this->est_working_time = array(
"h" => (
int) $hour,
"m" => (
int) $min,
"s" => (
int) $sec);
690 $this->est_working_time = array(
691 'h' => (
int) substr($durationString, 0, 2),
692 'm' => (
int) substr($durationString, 3, 2),
693 's' => (
int) substr($durationString, 6, 2)
707 foreach ($array as
$key => $value) {
708 if (strcmp(
$key, $searchkey) == 0) {
762 require_once
'Services/Utilities/classes/class.ilUtil.php';
856 if (!$this->est_working_time) {
857 $this->est_working_time = array(
"h" => 0,
"m" => 0,
"s" => 0);
923 if (!strlen($this->external_id)) {
924 if ($this->
getId() > 0) {
925 return 'il_' . IL_INST_ID .
'_qst_' . $this->
getId();
927 return uniqid(
'',
true);
943 $ilDB = $DIC[
'ilDB'];
947 "SELECT points FROM qpl_questions WHERE question_id = %s",
967 $ilDB = $DIC[
'ilDB'];
970 "SELECT qpl_questions.*, qpl_qst_type.type_tag FROM qpl_qst_type, qpl_questions WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id",
990 $ilDB = $DIC[
'ilDB'];
993 "SELECT suggested_solution_id FROM qpl_sol_sug WHERE question_fi = %s",
1012 return $question->getSuggestedSolutionOutput();
1018 foreach ($this->suggested_solutions as $solution) {
1019 switch ($solution[
"type"]) {
1027 $possible_texts = array_values(array_filter(array(
1030 $this->lng->txt(
'tst_show_solution_suggested')
1033 require_once
'Services/WebAccessChecker/classes/class.ilWACSignedPath.php';
1038 $solutionValue = $solution[
"value"];
1039 $solutionValue = $this->
fixSvgToPng($solutionValue);
1045 return join(
"<br />",
$output);
1059 $ilDB = $DIC[
'ilDB'];
1062 "SELECT * FROM qpl_sol_sug WHERE question_fi = %s AND subquestion_index = %s",
1063 array(
'integer',
'integer'),
1064 array($question_id, $subquestion_index)
1066 if (
$result->numRows() == 1) {
1069 "internal_link" =>
$row[
"internal_link"],
1070 "import_id" =>
$row[
"import_id"]
1097 $ilDB = $DIC[
'ilDB'];
1100 if (is_null(
$pass)) {
1101 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
1105 "SELECT * FROM tst_test_result WHERE active_fi = %s AND question_fi = %s AND pass = %s",
1106 array(
'integer',
'integer',
'integer'),
1107 array($active_id, $question_id,
$pass)
1109 if (
$result->numRows() == 1) {
1126 return round(self::_getReachedPoints($active_id, $this->
getId(),
$pass), 2);
1153 if (is_null(
$pass)) {
1154 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1164 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
1166 $requestsStatisticData = $hintTracking->getRequestStatisticDataByQuestionAndTestpass();
1167 $reached_points = $reached_points - $requestsStatisticData->getRequestsPoints();
1172 return $reached_points;
1187 $ilDB = $DIC[
'ilDB'];
1190 if (is_null(
$pass)) {
1191 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1199 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
1201 $requestsStatisticData = $questionHintTracking->getRequestStatisticDataByQuestionAndTestpass();
1202 $reached_points = $reached_points - $requestsStatisticData->getRequestsPoints();
1213 if (is_null($reached_points)) {
1214 $reached_points = 0;
1218 $existingSolutions = $this->lookupForExistingSolutions($active_id,
$pass);
1220 $this->
getProcessLocker()->executeUserQuestionResultUpdateOperation(
function () use (
$ilDB, $active_id,
$pass, $reached_points, $requestsStatisticData, $isAnswered, $existingSolutions) {
1222 DELETE FROM tst_test_result 1224 WHERE active_fi = %s 1225 AND question_fi = %s 1229 $types = array(
'integer',
'integer',
'integer');
1232 if ($this->
getStep() !== null) {
1237 $types[] =
'integer';
1242 if ($existingSolutions[
'authorized']) {
1243 $next_id =
$ilDB->nextId(
"tst_test_result");
1245 'test_result_id' => array(
'integer', $next_id),
1246 'active_fi' => array(
'integer', $active_id),
1247 'question_fi' => array(
'integer', $this->
getId()),
1248 'pass' => array(
'integer',
$pass),
1249 'points' => array(
'float', $reached_points),
1250 'tstamp' => array(
'integer', time()),
1251 'hint_count' => array(
'integer', $requestsStatisticData->getRequestsCount()),
1252 'hint_points' => array(
'float', $requestsStatisticData->getRequestsPoints()),
1253 'answered' => array(
'integer', $isAnswered)
1256 if ($this->
getStep() !== null) {
1257 $fieldData[
'step'] = array(
'integer', $this->
getStep());
1260 $ilDB->insert(
'tst_test_result', $fieldData);
1265 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1272 "log_user_answered_question",
1286 include_once
'Modules/Course/classes/class.ilCourseObjectiveResult.php';
1304 $saveStatus =
false;
1306 $this->
getProcessLocker()->executePersistWorkingStateLockOperation(
function () use ($active_id,
$pass, $authorized, $obligationsEnabled, &$saveStatus) {
1308 if (
$pass === null) {
1309 require_once
'Modules/Test/classes/class.ilObjTest.php';
1361 $ilDB = $DIC[
'ilDB'];
1363 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1364 include_once
"./Modules/Test/classes/class.assMarkSchema.php";
1369 SELECT tst_pass_result.* 1370 FROM tst_pass_result 1371 WHERE active_fi = %s 1377 array(
'integer',
'integer'),
1378 array($active_id,
$pass)
1383 $max =
$row[
'maxpoints'];
1384 $reached =
$row[
'points'];
1386 $obligationsAnswered = (int)
$row[
'obligations_answered'];
1388 include_once
"./Modules/Test/classes/class.assMarkSchema.php";
1390 $percentage = (!$max) ? 0 : ($reached / $max) * 100.0;
1392 $mark = ASS_MarkSchema::_getMatchingMarkFromActiveId($active_id, $percentage);
1394 $isPassed = ($mark[
"passed"] ? 1 : 0);
1395 $isFailed = (!$mark[
"passed"] ? 1 : 0);
1397 $userTestResultUpdateCallback =
function () use (
$ilDB, $active_id,
$pass, $max, $reached, $isFailed, $isPassed, $obligationsAnswered,
$row, $mark) {
1398 $passedOnceBefore = 0;
1399 $query =
"SELECT passed_once FROM tst_result_cache WHERE active_fi = %s";
1402 $passedOnceBefore = (int)
$row[
'passed_once'];
1405 $passedOnce = (int) ($isPassed || $passedOnceBefore);
1408 "DELETE FROM tst_result_cache WHERE active_fi = %s",
1413 $ilDB->insert(
'tst_result_cache', array(
1414 'active_fi' => array(
'integer', $active_id),
1415 'pass' => array(
'integer', strlen(
$pass) ?
$pass : 0),
1416 'max_points' => array(
'float', strlen($max) ? $max : 0),
1417 'reached_points' => array(
'float', strlen($reached) ? $reached : 0),
1418 'mark_short' => array(
'text', strlen($mark[
"short_name"]) ? $mark[
"short_name"] :
" "),
1419 'mark_official' => array(
'text', strlen($mark[
"official_name"]) ? $mark[
"official_name"] :
" "),
1420 'passed_once' => array(
'integer', $passedOnce),
1421 'passed' => array(
'integer', $isPassed),
1422 'failed' => array(
'integer', $isFailed),
1423 'tstamp' => array(
'integer', time()),
1424 'hint_count' => array(
'integer',
$row[
'hint_count']),
1425 'hint_points' => array(
'float',
$row[
'hint_points']),
1426 'obligations_answered' => array(
'integer', $obligationsAnswered)
1431 $processLocker->executeUserTestResultUpdateLockOperation($userTestResultUpdateCallback);
1433 $userTestResultUpdateCallback();
1441 $ilDB = $DIC[
'ilDB'];
1443 include_once
"./Modules/Test/classes/class.ilObjTest.php";
1445 if (self::getResultGateway() !== null) {
1446 $data = self::getResultGateway()->getQuestionCountAndPointsForPassOfParticipant($active_id,
$pass);
1447 $time = self::getResultGateway()->getWorkingTimeOfParticipantForPass($active_id,
$pass);
1458 SELECT SUM(points) reachedpoints, 1459 SUM(hint_count) hint_count, 1460 SUM(hint_points) hint_points, 1461 COUNT(DISTINCT(question_fi)) answeredquestions 1462 FROM tst_test_result 1463 WHERE active_fi = %s 1466 array(
'integer',
'integer'),
1467 array($active_id,
$pass)
1471 if ($obligationsEnabled) {
1473 SELECT answered answ 1474 FROM tst_test_question 1475 INNER JOIN tst_active 1477 AND tst_test_question.test_fi = tst_active.test_fi 1478 LEFT JOIN tst_test_result 1479 ON tst_test_result.active_fi = %s 1480 AND tst_test_result.pass = %s 1481 AND tst_test_question.question_fi = tst_test_result.question_fi 1482 WHERE obligatory = 1';
1484 $result_obligatory =
$ilDB->queryF(
1486 array(
'integer',
'integer',
'integer'),
1487 array($active_id, $active_id,
$pass)
1490 $obligations_answered = 1;
1492 while ($row_obligatory =
$ilDB->fetchAssoc($result_obligatory)) {
1493 if (!(
int) $row_obligatory[
'answ']) {
1494 $obligations_answered = 0;
1499 $obligations_answered = 1;
1504 if (
$row[
'reachedpoints'] === null) {
1505 $row[
'reachedpoints'] = 0;
1507 if (
$row[
'hint_count'] === null) {
1508 $row[
'hint_count'] = 0;
1510 if (
$row[
'hint_points'] === null) {
1511 $row[
'hint_points'] = 0;
1516 $updatePassResultCallback =
function () use (
$ilDB,
$data, $active_id,
$pass,
$row,
$time, $obligations_answered, $exam_identifier) {
1522 'active_fi' => array(
'integer', $active_id),
1523 'pass' => array(
'integer', strlen(
$pass) ?
$pass : 0)),
1525 'points' => array(
'float',
$row[
'reachedpoints'] ?
$row[
'reachedpoints'] : 0),
1526 'maxpoints' => array(
'float',
$data[
'points']),
1527 'questioncount' => array(
'integer',
$data[
'count']),
1528 'answeredquestions' => array(
'integer', $row[
'answeredquestions']),
1529 'workingtime' => array(
'integer',
$time),
1530 'tstamp' => array(
'integer', time()),
1531 'hint_count' => array(
'integer', $row[
'hint_count']),
1532 'hint_points' => array(
'float', $row[
'hint_points']),
1533 'obligations_answered' => array(
'integer', $obligations_answered),
1534 'exam_id' => array(
'text', $exam_identifier)
1540 $processLocker->executeUserPassResultUpdateLockOperation($updatePassResultCallback);
1542 $updatePassResultCallback();
1549 'active_fi' => $active_id,
1551 'points' => (
$row[
"reachedpoints"]) ?
$row[
"reachedpoints"] : 0,
1552 'maxpoints' =>
$data[
"points"],
1553 'questioncount' =>
$data[
"count"],
1554 'answeredquestions' => $row[
"answeredquestions"],
1555 'workingtime' =>
$time,
1557 'hint_count' => $row[
'hint_count'],
1558 'hint_points' => $row[
'hint_points'],
1559 'obligations_answered' => $obligations_answered,
1560 'exam_id' => $exam_identifier
1571 public static function logAction($logtext =
"", $active_id =
"", $question_id =
"")
1574 if (strlen($question_id)) {
1578 require_once
'Modules/Test/classes/class.ilObjAssessmentFolder.php';
1579 require_once
'Modules/Test/classes/class.ilObjTest.php';
1599 $mediatempdir = CLIENT_WEB_DIR .
"/assessment/temp";
1600 if (!@is_dir($mediatempdir)) {
1603 $temp_name = tempnam($mediatempdir,
$name .
"_____");
1604 $temp_name = str_replace(
"\\",
"/", $temp_name);
1605 @unlink($temp_name);
1606 if (!ilUtil::moveUploadedFile($file,
$name, $temp_name)) {
1620 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/solution/";
1631 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/java/";
1642 if ($question_id === null) {
1646 if ($object_id === null) {
1655 return CLIENT_WEB_DIR .
"/assessment/{$parentObjectId}/{$questionId}/images/";
1666 return CLIENT_WEB_DIR .
"/assessment/$this->obj_id/$this->id/flash/";
1677 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1689 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1704 if (!$this->export_image_path) {
1705 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1721 include_once
"./Services/Utilities/classes/class.ilUtil.php";
1743 if (!count($solution)) {
1756 $ilDB = $DIC[
'ilDB'];
1758 if (is_null(
$pass)) {
1762 if ($this->
getStep() !== null) {
1766 WHERE active_fi = %s 1767 AND question_fi = %s 1771 ORDER BY solution_id";
1775 array(
'integer',
'integer',
'integer',
'integer',
'integer'),
1782 WHERE active_fi = %s 1783 AND question_fi = %s 1786 ORDER BY solution_id 1791 array(
'integer',
'integer',
'integer',
'integer'),
1792 array($active_id, $this->
getId(),
$pass, (
int) $authorized)
1814 $ilDB = $DIC[
'ilDB'];
1816 if ($question_id < 1) {
1817 $question_id = $this->
getId();
1820 "SELECT COUNT(qpl_questions.question_id) question_count FROM qpl_questions, tst_test_question WHERE qpl_questions.original_id = %s AND qpl_questions.question_id = tst_test_question.question_fi",
1825 $count =
$row[
"question_count"];
1829 SELECT tst_active.test_fi 1831 INNER JOIN tst_test_rnd_qst ON tst_test_rnd_qst.question_fi = qpl_questions.question_id 1832 INNER JOIN tst_active ON tst_active.active_id = tst_test_rnd_qst.active_fi 1833 WHERE qpl_questions.original_id = %s 1834 GROUP BY tst_active.test_fi",
1852 $ilDB = $DIC[
'ilDB'];
1854 if ($question_id < 1) {
1858 "SELECT original_id FROM qpl_questions WHERE question_id = %s",
1863 return (
$row[
"original_id"] > 0) ? true :
false;
1874 $keys = array_keys($array);
1891 $ilDB = $DIC[
'ilDB'];
1894 "SELECT qpl_qst_type.type_tag FROM qpl_qst_type, qpl_questions WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id",
1899 return $data[
"type_tag"];
1933 $ilDB = $DIC[
'ilDB'];
1936 if (!is_array($answer_table_name)) {
1937 $answer_table_name = array($answer_table_name);
1940 foreach ($answer_table_name as
$table) {
1941 if (strlen($table)) {
1942 $affectedRows =
$ilDB->manipulateF(
1943 "DELETE FROM $table WHERE question_fi = %s",
1960 $ilDB = $DIC[
'ilDB'];
1964 if (!is_array($additional_table_name)) {
1965 $additional_table_name = array($additional_table_name);
1968 foreach ($additional_table_name as
$table) {
1969 if (strlen($table)) {
1970 $affectedRows =
$ilDB->manipulateF(
1971 "DELETE FROM $table WHERE question_fi = %s",
1987 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
1999 public function delete($question_id)
2002 $ilDB = $DIC[
'ilDB'];
2005 if ($question_id < 1) {
2010 "SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
2014 if (
$result->numRows() == 1) {
2023 $ilLog->write(
"EXCEPTION: Could not delete page of question $question_id: $e");
2027 $affectedRows =
$ilDB->manipulateF(
2028 "DELETE FROM qpl_questions WHERE question_id = %s",
2032 if ($affectedRows == 0) {
2042 $ilLog->write(
"EXCEPTION: Could not delete additional table data of question $question_id: $e");
2048 $affectedRows =
$ilDB->manipulateF(
2049 "DELETE FROM tst_test_question WHERE question_fi = %s",
2054 $ilLog->write(
"EXCEPTION: Could not delete delete question $question_id from a test: $e");
2060 $affectedRows =
$ilDB->manipulateF(
2061 "DELETE FROM qpl_sol_sug WHERE question_fi = %s",
2066 $ilLog->write(
"EXCEPTION: Could not delete suggested solutions of question $question_id: $e");
2071 $directory = CLIENT_WEB_DIR .
"/assessment/" .
$obj_id .
"/$question_id";
2072 if (preg_match(
"/\d+/",
$obj_id)
and preg_match(
"/\d+/", $question_id)
and is_dir($directory)) {
2073 include_once
"./Services/Utilities/classes/class.ilUtil.php";
2077 $ilLog->write(
"EXCEPTION: Could not delete question file directory $directory of question $question_id: $e");
2082 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2088 foreach (
$mobs as $mob) {
2096 $ilLog->write(
"EXCEPTION: Error deleting the media objects of question $question_id: $e");
2100 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
2101 ilAssQuestionHintTracking::deleteRequestsByQuestionIds(array($question_id));
2103 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
2106 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
2108 $assignmentList->setParentObjId(
$obj_id);
2109 $assignmentList->setQuestionIdFilter($question_id);
2110 $assignmentList->loadFromDb();
2111 foreach ($assignmentList->getAssignmentsByQuestionId($question_id) as $assignment) {
2113 $assignment->deleteFromDb();
2120 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
2123 $ilLog->write(
"EXCEPTION: Error updating the question pool question count of question pool " . $this->
getObjId() .
" when deleting question $question_id: $e");
2134 require_once
'Services/Taxonomy/classes/class.ilObjTaxonomy.php';
2135 require_once
'Services/Taxonomy/classes/class.ilTaxNodeAssignment.php';
2138 foreach ($taxIds as $taxId) {
2140 $taxNodeAssignment->deleteAssignmentsOfItem($this->
getId());
2161 $ilDB = $DIC[
'ilDB'];
2165 "SELECT question_id FROM qpl_questions WHERE original_id = %s OR question_id = %s",
2166 array(
'integer',
'integer'),
2167 array($a_q_id, $a_q_id)
2169 if (
$result->numRows() == 0) {
2172 $found_id = array();
2174 array_push($found_id,
$row[
"question_id"]);
2177 $result =
$ilDB->query(
"SELECT * FROM tst_test_result WHERE " .
$ilDB->in(
'question_fi', $found_id,
false,
'integer'));
2192 $ilDB = $DIC[
'ilDB'];
2194 "SELECT question_id FROM qpl_questions WHERE original_id = %s OR question_id = %s",
2195 array(
'integer',
'integer'),
2196 array($a_q_id, $a_q_id)
2198 if (
$result->numRows() == 0) {
2201 $found_id = array();
2203 array_push($found_id,
$row[
"question_id"]);
2205 $result =
$ilDB->query(
"SELECT * FROM tst_test_result WHERE " .
$ilDB->in(
'question_fi', $found_id,
false,
'integer'));
2208 $reached =
$row[
"points"];
2209 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
2211 array_push($answers, array(
"reached" => $reached,
"max" => $max));
2215 foreach ($answers as
$key => $value) {
2216 $max += $value[
"max"];
2217 $reached += $value[
"reached"];
2220 return $reached / $max;
2234 $ilDB = $DIC[
'ilDB'];
2236 "SELECT title FROM qpl_questions WHERE question_id = %s",
2240 if (
$result->numRows() == 1) {
2242 return $row[
"title"];
2256 $ilDB = $DIC[
'ilDB'];
2258 "SELECT question_text FROM qpl_questions WHERE question_id = %s",
2262 if (
$result->numRows() == 1) {
2264 return $row[
"question_text"];
2272 if (!file_exists($file)) {
2276 if (!is_file($file)) {
2280 if (!is_readable($file)) {
2289 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2291 foreach (
$mobs as $mob) {
2298 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
2300 foreach (
$mobs as $mob) {
2312 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2314 $this->page->setId($this->
getId());
2315 $this->page->setParentId($qpl_id);
2316 $this->page->setXMLContent(
"<PageObject><PageContent>" .
2317 "<Question QRef=\"il__qst_" . $this->
getId() .
"\"/>" .
2318 "</PageContent></PageObject>");
2319 $this->page->create();
2325 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2328 $xml = str_replace(
"il__qst_" . $a_q_id,
"il__qst_" . $this->
id,
$page->getXMLContent());
2329 $this->page->setXMLContent(
$xml);
2330 $this->page->updateFromXML();
2336 include_once
"./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php";
2338 return $page->getXMLContent();
2349 $ilDB = $DIC[
'ilDB'];
2351 if ($question_id < 1) {
2355 "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",
2359 if (
$result->numRows() == 1) {
2361 return $data[
"type_tag"];
2377 $ilDB = $DIC[
'ilDB'];
2379 if ($question_id < 1) {
2384 "SELECT title FROM qpl_questions WHERE qpl_questions.question_id = %s",
2388 if (
$result->numRows() == 1) {
2390 return $data[
"title"];
2407 'ok.svg' =>
'ok.png',
'not_ok.svg' =>
'not_ok.png',
2408 'checkbox_checked.svg' =>
'checkbox_checked.png',
2409 'checkbox_unchecked.svg' =>
'checkbox_unchecked.png',
2410 'radiobutton_checked.svg' =>
'radiobutton_checked.png',
2411 'radiobutton_unchecked.svg' =>
'radiobutton_unchecked.png' 2416 $needles = array_keys(self::$imageSourceFixReplaceMap);
2417 $replacements = array_values(self::$imageSourceFixReplaceMap);
2418 return str_replace($needles, $replacements, $imageFilenameContainingString);
2425 if (preg_match_all(
'/src="(.*?)"/m',
$html, $matches)) {
2426 $sources = $matches[1];
2428 $needleReplacementMap = array();
2430 foreach ($sources as $src) {
2433 if (file_exists($file)) {
2437 $levels = explode(DIRECTORY_SEPARATOR, $src);
2438 if (count($levels) < 5 || $levels[0] !=
'Customizing' || $levels[2] !=
'skin') {
2444 if ($levels[4] ==
'Modules' || $levels[4] ==
'Services') {
2445 $component = $levels[4] . DIRECTORY_SEPARATOR . $levels[5];
2451 if (count($needleReplacementMap)) {
2452 $html = str_replace(array_keys($needleReplacementMap), array_values($needleReplacementMap),
$html);
2468 $ilDB = $DIC[
'ilDB'];
2471 "SELECT external_id FROM qpl_questions WHERE question_id = %s",
2475 if (
$result->numRows() == 1) {
2477 $this->external_id =
$data[
'external_id'];
2481 "SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
2483 array($this->
getId())
2485 $this->suggested_solutions = array();
2487 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2490 $this->suggested_solutions[
$row[
"subquestion_index"]] = array(
2491 "type" => $row[
"type"],
2493 "internal_link" => $row[
"internal_link"],
2494 "import_id" => $row[
"import_id"]
2509 $ilDB = $DIC[
'ilDB'];
2514 $estw_time = sprintf(
"%02d:%02d:%02d", $estw_time[
'h'], $estw_time[
'm'], $estw_time[
's']);
2517 if ($a_create_page) {
2524 $next_id =
$ilDB->nextId(
'qpl_questions');
2525 $affectedRows =
$ilDB->insert(
"qpl_questions", array(
2526 "question_id" => array(
"integer", $next_id),
2528 "obj_fi" => array(
"integer",
$obj_id),
2529 "title" => array(
"text", null),
2530 "description" => array(
"text", null),
2531 "author" => array(
"text", $this->
getAuthor()),
2532 "owner" => array(
"integer",
$ilUser->getId()),
2533 "question_text" => array(
"clob", null),
2534 "points" => array(
"float", 0),
2536 "working_time" => array(
"text", $estw_time),
2537 "complete" => array(
"text", $complete),
2538 "created" => array(
"integer", time()),
2539 "original_id" => array(
"integer", null),
2540 "tstamp" => array(
"integer", $tstamp),
2544 $this->
setId($next_id);
2546 if ($a_create_page) {
2554 return $this->
getId();
2560 $ilDB = $DIC[
'ilDB'];
2563 $estw_time = sprintf(
"%02d:%02d:%02d", $estw_time[
'h'], $estw_time[
'm'], $estw_time[
's']);
2566 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2567 if ($this->
getId() == -1) {
2569 $next_id =
$ilDB->nextId(
'qpl_questions');
2570 $affectedRows =
$ilDB->insert(
"qpl_questions", array(
2571 "question_id" => array(
"integer", $next_id),
2573 "obj_fi" => array(
"integer", $this->
getObjId()),
2574 "title" => array(
"text", $this->
getTitle()),
2575 "description" => array(
"text", $this->
getComment()),
2576 "author" => array(
"text", $this->
getAuthor()),
2577 "owner" => array(
"integer", $this->
getOwner()),
2580 "working_time" => array(
"text", $estw_time),
2581 "nr_of_tries" => array(
"integer", $this->
getNrOfTries()),
2582 "created" => array(
"integer", time()),
2584 "tstamp" => array(
"integer", time()),
2588 $this->
setId($next_id);
2593 $affectedRows =
$ilDB->update(
"qpl_questions", array(
2594 "obj_fi" => array(
"integer", $this->
getObjId()),
2595 "title" => array(
"text", $this->
getTitle()),
2596 "description" => array(
"text", $this->
getComment()),
2597 "author" => array(
"text", $this->
getAuthor()),
2600 "nr_of_tries" => array(
"integer", $this->
getNrOfTries()),
2601 "working_time" => array(
"text", $estw_time),
2602 "tstamp" => array(
"integer", time()),
2603 'complete' => array(
'integer', $this->
isComplete()),
2606 "question_id" => array(
"integer", $this->
getId())
2620 $ilDB = $DIC[
'ilDB'];
2622 $this->updateSuggestedSolutions();
2633 $affectedRows =
$ilDB->manipulateF(
2634 "UPDATE qpl_questions SET tstamp = %s, owner = %s, complete = %s WHERE question_id = %s",
2635 array(
'integer',
'integer',
'integer',
'text'),
2636 array(time(), ($this->
getOwner() <= 0) ? $this->
ilias->account->id : $this->getOwner(), $complete, $this->
getId())
2640 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
2651 self::saveOriginalId($this->
getId(), $newId);
2656 $query =
"UPDATE qpl_questions SET tstamp = %s, original_id = %s WHERE question_id = %s";
2658 $GLOBALS[
'DIC'][
'ilDB']->manipulateF(
2660 array(
'integer',
'integer',
'text'),
2661 array(time(), $originalId, $questionId)
2667 $query =
"UPDATE qpl_questions SET tstamp = %s, original_id = NULL WHERE question_id = %s";
2669 $GLOBALS[
'DIC'][
'ilDB']->manipulateF(
2671 array(
'integer',
'text'),
2672 array(time(), $questionId)
2679 protected function onDuplicate($originalParentId, $originalQuestionId, $duplicateParentId, $duplicateQuestionId)
2684 $this->feedbackOBJ->duplicateFeedback($originalQuestionId, $duplicateQuestionId);
2700 $this->feedbackOBJ->syncFeedback($origQuestionId, $dupQuestionId);
2706 protected function onCopy($sourceParentId, $sourceQuestionId, $targetParentId, $targetQuestionId)
2711 $this->feedbackOBJ->duplicateFeedback($sourceQuestionId, $targetQuestionId);
2726 $ilDB = $DIC[
'ilDB'];
2728 $affectedRows =
$ilDB->manipulateF(
2729 "DELETE FROM qpl_sol_sug WHERE question_fi = %s",
2731 array($this->
getId())
2734 include_once
"./Services/Link/classes/class.ilInternalLink.php";
2736 $this->suggested_solutions = array();
2749 if (array_key_exists($subquestion_index, $this->suggested_solutions)) {
2750 return $this->suggested_solutions[$subquestion_index];
2766 if (array_key_exists($subquestion_index, $this->suggested_solutions)) {
2767 $title = $this->suggested_solutions[$subquestion_index][
"internal_link"];
2786 if (strcmp($solution_id,
"") != 0) {
2789 $import_id = $solution_id;
2792 $this->suggested_solutions[$subquestion_index] = array(
2793 "internal_link" => $solution_id,
2794 "import_id" => $import_id
2807 foreach ($this->suggested_solutions as
$index => $solution) {
2808 if (strcmp($solution[
"type"],
"file") == 0) {
2810 $filepath_original = str_replace(
2811 "/{$this->obj_id}/{$this->id}/solution",
2812 "/$parent_id/$question_id/solution",
2815 if (!file_exists($filepath)) {
2820 if (!copy($filepath_original .
$filename, $filepath . $filename)) {
2821 $ilLog->write(
"File could not be duplicated!!!!",
$ilLog->ERROR);
2822 $ilLog->write(
"object: " . print_r($this,
true),
$ilLog->ERROR);
2838 $filepath_original = str_replace(
"/$this->id/solution",
"/$original_id/solution", $filepath);
2840 foreach ($this->suggested_solutions as
$index => $solution) {
2841 if (strcmp($solution[
"type"],
"file") == 0) {
2842 if (!file_exists($filepath_original)) {
2847 if (!@copy($filepath .
$filename, $filepath_original . $filename)) {
2848 $ilLog->write(
"File could not be duplicated!!!!",
$ilLog->ERROR);
2849 $ilLog->write(
"object: " . print_r($this,
true),
$ilLog->ERROR);
2861 foreach ($this->suggested_solutions as
$index => $solution) {
2862 if (strcmp($solution[
"type"],
"file") == 0) {
2864 $filepath_original = str_replace(
"/$this->obj_id/$this->id/solution",
"/$source_questionpool_id/$source_question_id/solution", $filepath);
2865 if (!file_exists($filepath)) {
2870 if (!copy($filepath_original .
$filename, $filepath . $filename)) {
2871 $ilLog->write(
"File could not be copied!!!!",
$ilLog->ERROR);
2872 $ilLog->write(
"object: " . print_r($this,
true),
$ilLog->ERROR);
2882 public function updateSuggestedSolutions(
$original_id =
"")
2885 $ilDB = $DIC[
'ilDB'];
2888 include_once
"./Services/Link/classes/class.ilInternalLink.php";
2889 $affectedRows =
$ilDB->manipulateF(
2890 "DELETE FROM qpl_sol_sug WHERE question_fi = %s",
2895 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2896 foreach ($this->suggested_solutions as
$index => $solution) {
2897 $next_id =
$ilDB->nextId(
'qpl_sol_sug');
2902 'suggested_solution_id' => array(
'integer', $next_id ),
2903 'question_fi' => array(
'integer',
$id ),
2904 'type' => array(
'text', $solution[
'type'] ),
2906 'internal_link' => array(
'text', $solution[
'internal_link'] ),
2907 'import_id' => array(
'text', null ),
2908 'subquestion_index' => array(
'integer',
$index ),
2909 'tstamp' => array(
'integer', time() ),
2912 if (preg_match(
"/il_(\d*?)_(\w+)_(\d+)/", $solution[
"internal_link"], $matches)) {
2931 public function saveSuggestedSolution(
$type, $solution_id =
"", $subquestion_index = 0, $value =
"")
2934 $ilDB = $DIC[
'ilDB'];
2936 $affectedRows =
$ilDB->manipulateF(
2937 "DELETE FROM qpl_sol_sug WHERE question_fi = %s AND subquestion_index = %s",
2938 array(
"integer",
"integer"),
2945 $next_id =
$ilDB->nextId(
'qpl_sol_sug');
2946 include_once(
"./Services/RTE/classes/class.ilRTE.php");
2948 $affectedRows =
$ilDB->insert(
2951 'suggested_solution_id' => array(
'integer', $next_id ),
2952 'question_fi' => array(
'integer', $this->
getId() ),
2953 'type' => array(
'text',
$type ),
2955 'internal_link' => array(
'text', $solution_id ),
2956 'import_id' => array(
'text', null ),
2957 'subquestion_index' => array(
'integer', $subquestion_index ),
2958 'tstamp' => array(
'integer', time() ),
2961 if ($affectedRows == 1) {
2962 $this->suggested_solutions[$subquestion_index] = array(
2965 "internal_link" => $solution_id,
2974 if (preg_match(
"/il_(\d+)_(\w+)_(\d+)/", $internal_link, $matches)) {
2975 include_once
"./Services/Link/classes/class.ilInternalLink.php";
2976 include_once
"./Modules/LearningModule/classes/class.ilLMObject.php";
2977 include_once
"./Modules/Glossary/classes/class.ilGlossaryTerm.php";
2978 switch ($matches[2]) {
2995 if (strcmp($resolved_link,
"") == 0) {
2996 $resolved_link = $internal_link;
2999 $resolved_link = $internal_link;
3001 return $resolved_link;
3007 $ilDB = $DIC[
'ilDB'];
3010 "SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
3016 $internal_link =
$row[
"internal_link"];
3017 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
3019 if (strcmp($internal_link, $resolved_link) != 0) {
3021 $affectedRows =
$ilDB->manipulateF(
3022 "UPDATE qpl_sol_sug SET internal_link = %s WHERE suggested_solution_id = %s",
3023 array(
'text',
'integer'),
3024 array($resolved_link,
$row[
"suggested_solution_id"])
3030 if ($resolvedlinks) {
3034 include_once
"./Services/Link/classes/class.ilInternalLink.php";
3038 "SELECT * FROM qpl_sol_sug WHERE question_fi = %s",
3044 if (preg_match(
"/il_(\d*?)_(\w+)_(\d+)/",
$row[
"internal_link"], $matches)) {
3055 $ilDB = $DIC[
'ilDB'];
3057 "lm" =>
"LearningModule",
3058 "pg" =>
"PageObject",
3059 "st" =>
"StructureObject",
3060 "git" =>
"GlossaryItem",
3061 "mob" =>
"MediaObject" 3064 if (preg_match(
"/il__(\w+)_(\d+)/",
$target, $matches)) {
3065 $type = $matches[1];
3067 include_once
"./Services/Utilities/classes/class.ilUtil.php";
3068 switch ($linktypes[$matches[1]]) {
3069 case "LearningModule":
3073 case "StructureObject":
3076 case "GlossaryItem":
3080 $href =
"./ilias.php?baseClass=ilLMPresentationGUI&obj_type=" . $linktypes[
$type] .
"&cmd=media&ref_id=" .
$_GET[
"ref_id"] .
"&mob_id=" .
$target_id;
3097 $ilDB = $DIC[
'ilDB'];
3099 "SELECT * FROM qpl_questions WHERE question_id = %s",
3105 if (
$row[
"original_id"] > 0) {
3106 return $row[
"original_id"];
3108 return $row[
"question_id"];
3118 $ilDB = $DIC[
'ilDB'];
3121 SELECT COUNT(dupl.question_id) cnt 3122 FROM qpl_questions dupl 3123 INNER JOIN qpl_questions orig 3124 ON orig.question_id = dupl.original_id 3125 WHERE dupl.question_id = %s 3131 return $row[
'cnt'] > 0;
3137 $ilDB = $DIC[
'ilDB'];
3143 $originalObjId = self::lookupOriginalParentObjId($this->
getOriginalId());
3145 if (!$originalObjId) {
3155 $this->
setId($original);
3169 $this->updateSuggestedSolutions($original);
3190 $ilDB = $DIC[
'ilDB'];
3192 if ($question_id < 1) {
3197 "SELECT question_id FROM qpl_questions WHERE question_id = %s",
3201 if (
$result->numRows() == 1) {
3218 $ilDB = $DIC[
'ilDB'];
3220 if ($question_id < 1) {
3225 "SELECT question_id FROM qpl_questions INNER JOIN object_data ON obj_fi = obj_id WHERE question_id = %s AND type = 'qpl'",
3229 if (
$result->numRows() == 1) {
3245 return self::_instantiateQuestion($question_id);
3256 $ilDB = $DIC[
'ilDB'];
3259 if (strcmp($question_id,
"") != 0) {
3261 if (!strlen($question_type)) {
3265 $objectClassname = self::getObjectClassNameByQuestionType($question_type);
3269 $feedbackObjectClassname = self::getFeedbackClassNameByQuestionType($question_type);
3284 if (strcmp($this->points,
"") == 0) {
3300 $this->points = $a_points;
3311 return self::_getSolutionMaxPass($this->
getId(), $active_id);
3330 $ilDB = $DIC[
'ilDB'];
3333 "SELECT MAX(pass) maxpass FROM tst_test_result WHERE active_fi = %s AND question_fi = %s",
3334 array(
'integer',
'integer'),
3335 array($active_id, $question_id)
3337 if (
$result->numRows() == 1) {
3339 return $row[
"maxpass"];
3356 $ilDB = $DIC[
'ilDB'];
3358 if (($question_id < 1) || ($user_id < 1)) {
3363 "SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
3367 if (
$result->numRows() == 1) {
3369 $qpl_object_id =
$row[
"obj_fi"];
3370 include_once
"./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
3386 $ilDB = $DIC[
'ilDB'];
3388 if ($question_id < 1) {
3392 "SELECT test_random_question_id FROM tst_test_rnd_qst WHERE question_fi = %s",
3418 $reachedPoints = $reachedPoints - $requestsStatisticData->getRequestsPoints();
3420 return $reachedPoints;
3460 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3462 if ($count_system == 1) {
3468 if ($score_cutting == 0) {
3486 return self::lookupResultRecordExist($active_id, $question_id,
$pass);
3491 $ilDB = $DIC[
'ilDB'];
3494 if (is_null(
$pass)) {
3495 include_once
"./Modules/TestQuestionPool/classes/class.assQuestion.php";
3499 "SELECT solution_id FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
3500 array(
'integer',
'integer',
'integer'),
3501 array($active_id, $question_id,
$pass)
3520 $ilDB = $DIC[
'ilDB'];
3523 "SELECT DISTINCT(question_fi) FROM tst_test_result JOIN tst_active " .
3524 "ON (active_id = active_fi) " .
3525 "WHERE " .
$ilDB->in(
'question_fi', $a_question_ids,
false,
'integer') .
3526 " AND user_fi = %s",
3530 return (
$res->numRows() == count($a_question_ids)) ?
true :
false;
3554 include_once
"./Services/Utilities/classes/class.ilUtil.php";
3568 for (
$i = 0;
$i < $a_material->getMaterialCount();
$i++) {
3569 $material = $a_material->getMaterial(
$i);
3570 if (strcmp($material[
"type"],
"mattext") == 0) {
3571 $result .= $material[
"material"]->getContent();
3573 if (strcmp($material[
"type"],
"matimage") == 0) {
3574 $matimage = $material[
"material"];
3575 if (preg_match(
"/(il_([0-9]+)_mob_([0-9]+))/", $matimage->getLabel(), $matches)) {
3577 if (!is_array(
$_SESSION[
"import_mob_xhtml"])) {
3578 $_SESSION[
"import_mob_xhtml"] = array();
3580 array_push(
$_SESSION[
"import_mob_xhtml"], array(
"mob" => $matimage->getLabel(),
"uri" => $matimage->getUri()));
3595 public function addQTIMaterial(&$a_xml_writer, $a_material, $close_material_tag =
true, $add_mobs =
true)
3597 include_once
"./Services/RTE/classes/class.ilRTE.php";
3598 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
3600 $a_xml_writer->xmlStartTag(
"material");
3602 "texttype" =>
"text/plain" 3604 if ($this->
isHTML($a_material)) {
3605 $attrs[
"texttype"] =
"text/xhtml";
3610 foreach (
$mobs as $mob) {
3611 $moblabel =
"il_" . IL_INST_ID .
"_mob_" . $mob;
3612 if (strpos($a_material,
"mm_$mob") !==
false) {
3616 "label" => $moblabel,
3617 "uri" =>
"objects/" .
"il_" . IL_INST_ID .
"_mob_" . $mob .
"/" . $mob_obj->getTitle()
3620 $a_xml_writer->xmlElement(
"matimage", $imgattrs, null);
3624 if ($close_material_tag) {
3625 $a_xml_writer->xmlEndTag(
"material");
3633 if (preg_match(
"/.*\.(png|jpg|gif|jpeg)$/i", $plain_image_filename, $matches)) {
3634 $extension =
"." . $matches[1];
3638 $plain_image_filename = uniqid($plain_image_filename . microtime(
true));
3641 $hashed_filename = md5($plain_image_filename) . $extension;
3643 return $hashed_filename;
3659 $ilDB = $DIC[
'ilDB'];
3662 if (is_null(
$pass)) {
3669 "SELECT points FROM tst_test_result WHERE active_fi = %s AND question_fi = %s AND pass = %s",
3670 array(
'integer',
'integer',
'integer'),
3671 array($active_id, $question_id,
$pass)
3673 $manual = ($manualscoring) ? 1 : 0;
3674 $rowsnum =
$result->numRows();
3677 $old_points =
$row[
"points"];
3679 $affectedRows =
$ilDB->manipulateF(
3680 "UPDATE tst_test_result SET points = %s, manual = %s, tstamp = %s WHERE active_fi = %s AND question_fi = %s AND pass = %s",
3681 array(
'float',
'integer',
'integer',
'integer',
'integer',
'integer'),
3682 array(
$points, $manual, time(), $active_id, $question_id,
$pass)
3686 $next_id =
$ilDB->nextId(
'tst_test_result');
3687 $affectedRows =
$ilDB->manipulateF(
3688 "INSERT INTO tst_test_result (test_result_id, active_fi, question_fi, points, pass, manual, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
3689 array(
'integer',
'integer',
'integer',
'float',
'integer',
'integer',
'integer'),
3690 array($next_id, $active_id, $question_id,
$points,
$pass, $manual, time())
3694 if (self::isForcePassResultUpdateEnabled() || $old_points !=
$points || !$rowsnum) {
3695 assQuestion::_updateTestPassResults($active_id,
$pass, $obligationsEnabled);
3697 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3698 include_once
'./Modules/Course/classes/class.ilCourseObjectiveResult.php';
3701 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
3706 include_once
"./Modules/Test/classes/class.ilObjTestAccess.php";
3760 $ilDB = $DIC[
'ilDB'];
3763 "SELECT question_type_id FROM qpl_qst_type WHERE type_tag = %s",
3767 if (
$result->numRows() == 1) {
3769 return $row[
"question_type_id"];
3774 public function syncHints()
3777 $ilDB = $DIC[
'ilDB'];
3781 "DELETE FROM qpl_hints WHERE qht_question_fi = %s",
3783 array($this->original_id)
3788 "SELECT * FROM qpl_hints WHERE qht_question_fi = %s",
3790 array($this->
getId())
3796 $next_id =
$ilDB->nextId(
'qpl_hints');
3801 'qht_hint_id' => array(
'integer', $next_id),
3802 'qht_question_fi' => array(
'integer', $this->original_id),
3803 'qht_hint_index' => array(
'integer',
$row[
"qht_hint_index"]),
3804 'qht_hint_points' => array(
'integer',
$row[
"qht_hint_points"]),
3805 'qht_hint_text' => array(
'text',
$row[
"qht_hint_text"]),
3821 $collected .= $this->feedbackOBJ->getGenericFeedbackContent($this->
getId(),
false);
3822 $collected .= $this->feedbackOBJ->getGenericFeedbackContent($this->
getId(),
true);
3823 $collected .= $this->feedbackOBJ->getAllSpecificAnswerFeedbackContents($this->
getId());
3825 foreach ($this->suggested_solutions as $solution_array) {
3826 $collected .= $solution_array[
"value"];
3829 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
3831 foreach ($questionHintList as $questionHint) {
3833 $collected .= $questionHint->getText();
3846 include_once(
"./Services/RTE/classes/class.ilRTE.php");
3858 $ilDB = $DIC[
'ilDB'];
3861 "SELECT question_id FROM qpl_questions WHERE original_id = %s",
3863 array($this->
getId())
3865 $instances = array();
3868 array_push($ids,
$row[
"question_id"]);
3870 foreach ($ids as $question_id) {
3873 "SELECT tst_tests.obj_fi FROM tst_tests, tst_test_question WHERE tst_test_question.question_fi = %s AND tst_test_question.test_fi = tst_tests.test_id",
3882 "SELECT tst_tests.obj_fi FROM tst_tests, tst_test_rnd_qst, tst_active WHERE tst_test_rnd_qst.active_fi = tst_active.active_id AND tst_test_rnd_qst.question_fi = %s AND tst_tests.test_id = tst_active.test_fi",
3890 include_once
"./Modules/Test/classes/class.ilObjTest.php";
3891 foreach ($instances as
$key => $value) {
3899 include_once
"./Modules/Test/classes/class.ilObjAssessmentFolder.php";
3902 if (in_array($questiontype, $scoring)) {
3919 $ilDB = $DIC[
'ilDB'];
3921 "SELECT * FROM tst_active WHERE active_id = %s",
3927 return array(
"user_id" =>
$row[
"user_fi"],
"test_id" =>
$row[
"test_fi"]);
3942 if (self::isCoreQuestionType($question_type)) {
3943 self::includeCoreClass($question_type, $gui);
3945 self::includePluginClass($question_type, $gui);
3951 return $questionType .
'GUI';
3956 return $questionType;
3961 return str_replace(
'ass',
'ilAss', $questionType) .
'Feedback';
3966 $guiClassName = self::getGuiClassNameByQuestionType($questionType);
3967 return file_exists(
"Modules/TestQuestionPool/classes/class.{$guiClassName}.php");
3972 if ($withGuiClass) {
3973 $guiClassName = self::getGuiClassNameByQuestionType($questionType);
3974 require_once
"Modules/TestQuestionPool/classes/class.{$guiClassName}.php";
3978 $objectClassName = self::getObjectClassNameByQuestionType($questionType);
3979 require_once
"Modules/TestQuestionPool/classes/class.{$objectClassName}.php";
3982 $feedbackClassName = self::getFeedbackClassNameByQuestionType($questionType);
3983 require_once
"Modules/TestQuestionPool/classes/feedback/class.{$feedbackClassName}.php";
3989 $ilPluginAdmin = $DIC[
'ilPluginAdmin'];
3992 self::getObjectClassNameByQuestionType($questionType),
3993 self::getFeedbackClassNameByQuestionType($questionType)
3996 if ($withGuiClass) {
3997 $classes[] = self::getGuiClassNameByQuestionType($questionType);
4000 $pl_names = $ilPluginAdmin->getActivePluginsForSlot(
IL_COMP_MODULE,
"TestQuestionPool",
"qst");
4001 foreach ($pl_names as $pl_name) {
4003 if (strcmp($pl->getQuestionType(), $questionType) == 0) {
4004 foreach ($classes as $class) {
4005 $pl->includeClass(
"class.{$class}.php");
4021 if (file_exists(
"./Modules/TestQuestionPool/classes/class." . $type_tag .
".php")) {
4024 return $lng->txt($type_tag);
4027 $ilPluginAdmin = $DIC[
'ilPluginAdmin'];
4028 $pl_names = $ilPluginAdmin->getActivePluginsForSlot(
IL_COMP_MODULE,
"TestQuestionPool",
"qst");
4029 foreach ($pl_names as $pl_name) {
4031 if (strcmp($pl->getQuestionType(), $type_tag) == 0) {
4032 return $pl->getQuestionTypeTranslation();
4050 return self::instantiateQuestionGUI($question_id);
4064 $ilDB = $DIC[
'ilDB'];
4068 if (strcmp($a_question_id,
"") != 0) {
4073 $question_type_gui = self::getGuiClassNameByQuestionType($question_type);
4074 $question_gui =
new $question_type_gui();
4075 $question_gui->object->loadFromDb($a_question_id);
4077 $feedbackObjectClassname = self::getFeedbackClassNameByQuestionType($question_type);
4078 $question_gui->object->feedbackOBJ =
new $feedbackObjectClassname($question_gui->object,
$ilCtrl,
$ilDB,
$lng);
4080 $assSettings =
new ilSetting(
'assessment');
4081 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionProcessLockerFactory.php';
4083 $processLockerFactory->setQuestionId($question_gui->object->getId());
4084 $processLockerFactory->setUserId(
$ilUser->getId());
4085 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
4087 $question_gui->object->setProcessLocker($processLockerFactory->getLocker());
4091 $ilLog->write(
'Instantiate question called without question id. (instantiateQuestionGUI@assQuestion)',
$ilLog->WARNING);
4094 return $question_gui;
4109 $worksheet->setFormattedExcelTitle($worksheet->getColumnCoord(0) . $startrow, $this->lng->txt($this->
getQuestionType()));
4110 $worksheet->setFormattedExcelTitle($worksheet->getColumnCoord(1) . $startrow, $this->
getTitle());
4122 return $this->
getId();
4142 case "est_working_time":
4166 case "suggested_solutions":
4173 if (array_key_exists($value, $this->arrData)) {
4174 return $this->arrData[$value];
4189 $this->
setId($value);
4209 case "est_working_time":
4210 if (is_array($value)) {
4230 $this->page = &$value;
4233 $this->arrData[
$key] = $value;
4245 $this->nr_of_tries = $a_nr_of_tries;
4250 $this->export_image_path = (string) $a_path;
4256 $ilDB = $DIC[
'ilDB'];
4258 if ($question_id < 1) {
4263 "SELECT question_fi FROM tst_test_question WHERE question_fi = %s AND test_fi = %s",
4264 array(
'integer',
'integer'),
4267 if (
$result->numRows() == 1) {
4290 require_once
'Modules/TestQuestionPool/classes/questions/class.ilAssSelfAssessmentQuestionFormatter.php';
4291 return new \ilAssSelfAssessmentQuestionFormatter();
4303 $this->prevent_rte_usage = $a_val;
4325 $this->feedbackOBJ->migrateContentForLearningModule($migrator, $this->
getId());
4351 $this->selfassessmenteditingmode = $a_selfassessmenteditingmode;
4371 $this->defaultnroftries = $a_defaultnroftries;
4394 $ilDB = $DIC[
'ilDB'];
4396 $query =
"SELECT obj_fi FROM qpl_questions WHERE question_id = %s";
4398 $res =
$ilDB->queryF(
$query, array(
'integer'), array((
int) $questionId));
4401 return $row[
'obj_fi'];
4416 return self::lookupParentObjId($originalQuestionId);
4421 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintList.php';
4425 require_once
'Modules/TestQuestionPool/classes/class.ilAssHintPage.php';
4427 foreach ($hintIds as $originalHintId => $duplicateHintId) {
4429 $originalXML = $originalPageObject->getXMLContent();
4432 $duplicatePageObject->setId($duplicateHintId);
4433 $duplicatePageObject->setParentId($this->
getId());
4434 $duplicatePageObject->setXMLContent($originalXML);
4435 $duplicatePageObject->createFromXML();
4443 $ilDB = $DIC[
'ilDB'];
4445 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
4447 $assignmentList->setParentObjId($srcParentId);
4448 $assignmentList->setQuestionIdFilter($srcQuestionId);
4449 $assignmentList->loadFromDb();
4451 foreach ($assignmentList->getAssignmentsByQuestionId($srcQuestionId) as $assignment) {
4454 $assignment->setParentObjId($trgParentId);
4455 $assignment->setQuestionId($trgQuestionId);
4456 $assignment->saveToDb();
4463 $ilDB = $DIC[
'ilDB'];
4465 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
4467 $assignmentList->setParentObjId($trgParentId);
4468 $assignmentList->setQuestionIdFilter($trgQuestionId);
4469 $assignmentList->loadFromDb();
4471 foreach ($assignmentList->getAssignmentsByQuestionId($trgQuestionId) as $assignment) {
4474 $assignment->deleteFromDb();
4534 $ilDB = $DIC[
'ilDB'];
4537 SELECT count(active_fi) cnt 4541 WHERE active_fi = %s 4542 AND question_fi = %s 4548 array(
'integer',
'integer',
'integer'),
4549 array($activeId, $questionId,
$pass)
4554 return (
int)
$row[
'cnt'];
4577 require_once
'Modules/TestQuestionPool/exceptions/class.ilTestQuestionPoolException.php';
4620 self::ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT,
4621 self::ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT
4630 $this->questionChangeListeners[] = $listener;
4644 $listener->notifyQuestionCreated($this);
4651 $listener->notifyQuestionEdited($this);
4658 $listener->notifyQuestionDeleted($this);
4667 require_once
'Services/Html/classes/class.ilHtmlPurifierFactory.php';
4676 require_once
'Services/Html/classes/class.ilHtmlPurifierFactory.php';
4683 SELECT qpl_questions.*, 4684 {$this->getAdditionalTableName()}.* 4686 LEFT JOIN {$this->getAdditionalTableName()} 4687 ON {$this->getAdditionalTableName()}.question_fi = qpl_questions.question_id 4688 WHERE qpl_questions.question_id = %s 4715 $ilDB = $DIC[
'ilDB'];
4717 if ($this->
getStep() !== null) {
4721 WHERE active_fi = %s 4722 AND question_fi = %s 4728 return $ilDB->queryF(
4730 array(
'integer',
'integer',
'integer',
'integer',
'integer'),
4737 WHERE active_fi = %s 4738 AND question_fi = %s 4743 return $ilDB->queryF(
4745 array(
'integer',
'integer',
'integer',
'integer'),
4746 array($active_id, $this->
getId(),
$pass, (
int) $authorized)
4760 $ilDB = $DIC[
'ilDB'];
4762 return $ilDB->manipulateF(
4763 "DELETE FROM tst_solutions WHERE solution_id = %s",
4779 $ilDB = $DIC[
'ilDB'];
4782 "SELECT * FROM tst_solutions WHERE solution_id = %s",
4803 $this->
getProcessLocker()->executeUserSolutionUpdateLockOperation(
function () use ($active_id,
$pass) {
4819 $ilDB = $DIC[
'ilDB'];
4821 if ($this->
getStep() !== null) {
4823 DELETE FROM tst_solutions 4824 WHERE active_fi = %s 4825 AND question_fi = %s 4831 return $ilDB->manipulateF(
4833 array(
'integer',
'integer',
'integer',
'integer',
'integer'),
4838 DELETE FROM tst_solutions 4839 WHERE active_fi = %s 4840 AND question_fi = %s 4845 return $ilDB->manipulateF(
4847 array(
'integer',
'integer',
'integer',
'integer'),
4848 array($active_id, $this->
getId(),
$pass, (
int) $authorized)
4868 $ilDB = $DIC[
'ilDB'];
4870 $next_id =
$ilDB->nextId(
"tst_solutions");
4873 "solution_id" => array(
"integer", $next_id),
4874 "active_fi" => array(
"integer", $active_id),
4875 "question_fi" => array(
"integer", $this->
getId()),
4876 "value1" => array(
"clob", $value1),
4877 "value2" => array(
"clob", $value2),
4878 "pass" => array(
"integer",
$pass),
4879 "tstamp" => array(
"integer", isset($tstamp) ? $tstamp : time()),
4880 'authorized' => array(
'integer', (
int) $authorized)
4883 if ($this->
getStep() !== null) {
4884 $fieldData[
'step'] = array(
"integer", $this->
getStep());
4887 return $ilDB->insert(
"tst_solutions", $fieldData);
4904 $ilDB = $DIC[
'ilDB'];
4907 "value1" => array(
"clob", $value1),
4908 "value2" => array(
"clob", $value2),
4909 "tstamp" => array(
"integer", time()),
4910 'authorized' => array(
'integer', (
int) $authorized)
4913 if ($this->
getStep() !== null) {
4914 $fieldData[
'step'] = array(
"integer", $this->
getStep());
4917 return $ilDB->update(
"tst_solutions", $fieldData, array(
4918 'solution_id' => array(
'integer', $solutionId)
4926 $ilDB = $DIC[
'ilDB'];
4929 'authorized' => array(
'integer', (
int) $authorized)
4933 $fieldData[
'tstamp'] = array(
'integer', time());
4937 'question_fi' => array(
'integer', $this->
getId()),
4938 'active_fi' => array(
'integer', $activeId),
4939 'pass' => array(
'integer',
$pass)
4942 if ($this->
getStep() !== null) {
4943 $whereData[
'step'] = array(
"integer", $this->
getStep());
4946 return $ilDB->update(
'tst_solutions', $fieldData, $whereData);
4954 return self::KEY_VALUES_IMPLOSION_SEPARATOR;
4958 return implode(self::getKeyValuesImplosionSeparator(), $keyValues);
4962 return explode(self::getKeyValuesImplosionSeparator(), $keyValues);
4967 foreach ($this->
getSolutionValues($activeId, $passIndex,
false) as $solutionRec) {
4968 if (0 == strlen($solutionRec[
'value1']) && 0 == strlen($solutionRec[
'value2'])) {
4976 return !strlen($solutionRecord[
'value1']) && !strlen($solutionRecord[
'value2']);
4982 $ilDB = $DIC[
'ilDB'];
4984 $types = array(
"integer",
"integer",
"integer",
"integer");
4985 $values = array($activeId, $this->
getId(), $passIndex, (
int) $authorized);
4986 $valuesCondition = array();
4988 foreach ($matchValues as $valueField => $value) {
4989 switch ($valueField) {
4992 $valuesCondition[] =
"{$valueField} = %s";
4998 require_once
'Modules/TestQuestionPool/exceptions/class.ilTestQuestionPoolException.php';
5003 $valuesCondition = implode(
' AND ', $valuesCondition);
5006 DELETE FROM tst_solutions 5007 WHERE active_fi = %s 5008 AND question_fi = %s 5011 AND $valuesCondition 5014 if ($this->
getStep() !== null) {
5015 $query .=
" AND step = %s ";
5016 $types[] =
'integer';
5026 $this->
saveCurrentSolution($activeId, $passIndex, $rec[
'value1'], $rec[
'value2'],
true, $rec[
'tstamp']);
5034 if (!count($intermediateSolution)) {
5042 if ($considerDummyRecordCreation) {
5064 return self::$resultGateway;
5072 $this->step =
$step;
5092 return gmdate(
'H:i:s',
$time);
5102 $time_array = explode(
':',
$time);
5103 if (
sizeof($time_array) == 3) {
5104 $sec += $time_array[0] * 3600;
5105 $sec += $time_array[1] * 60;
5106 $sec += $time_array[2];
5113 return json_encode(array());
5121 $solutionAvailability = $this->lookupForExistingSolutions($active_id,
$pass);
5122 return (
bool) $solutionAvailability[
'intermediate'];
5126 $solutionAvailability = $this->lookupForExistingSolutions($active_id,
$pass);
5127 return (
bool) $solutionAvailability[
'authorized'];
5131 $solutionAvailability = $this->lookupForExistingSolutions($active_id,
$pass);
5132 return (
bool) $solutionAvailability[
'authorized'] || (bool) $solutionAvailability[
'intermediate'];
5141 protected function lookupMaxStep($active_id,
$pass)
5145 $ilDB = $DIC[
'ilDB'];
5148 "SELECT MAX(step) max_step FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
5149 array(
"integer",
"integer",
"integer"),
5155 $maxStep =
$row[
'max_step'];
5167 public function lookupForExistingSolutions($activeId,
$pass)
5171 $ilDB = $DIC[
'ilDB'];
5174 'authorized' =>
false,
5175 'intermediate' =>
false 5179 SELECT authorized, COUNT(*) cnt 5181 WHERE active_fi = %s 5182 AND question_fi = %s 5186 if ($this->
getStep() !== null) {
5197 if (
$row[
'authorized']) {
5198 $return[
'authorized'] =
$row[
'cnt'] > 0;
5200 $return[
'intermediate'] =
$row[
'cnt'] > 0;
5220 $query =
"DELETE FROM tst_solutions WHERE question_fi = %s";
5222 $DIC->database()->manipulateF(
$query, array(
'integer'), array($this->
getId()));
5228 $ilDB = $DIC[
'ilDB'];
5231 DELETE FROM tst_solutions 5232 WHERE active_fi = %s 5233 AND question_fi = %s 5237 if ($this->
getStep() !== null) {
5241 return $ilDB->manipulateF(
5243 array(
'integer',
'integer',
'integer'),
5253 $this->
log($activeId,
"log_user_solution_willingly_deleted");
5255 self::_updateTestPassResults(
5267 $ilDB = $DIC[
'ilDB'];
5270 DELETE FROM tst_test_result 5271 WHERE active_fi = %s 5272 AND question_fi = %s 5276 if ($this->
getStep() !== null) {
5280 return $ilDB->manipulateF(
5282 array(
'integer',
'integer',
'integer'),
5290 $ilDB = $DIC[
'ilDB'];
5292 $IN_questionIds =
$ilDB->in(
'question_fi', $questionIds,
false,
'integer');
5296 FROM tst_test_result 5297 WHERE active_fi = %s 5304 array(
'integer',
'integer'),
5305 array($activeId,
$pass)
5308 return $row[
'cnt'] < count($questionIds);
5314 $ilDB = $DIC[
'ilDB'];
5316 $IN_questionIds =
$ilDB->in(
'question_fi', $questionIds,
false,
'integer');
5320 FROM tst_test_result 5321 WHERE active_fi = %s 5328 array(
'integer',
'integer'),
5329 array($activeId,
$pass)
5332 $questionsHavingResultRecord = array();
5335 $questionsHavingResultRecord[] =
$row[
'question_fi'];
5338 $questionsMissingResultRecordt = array_diff(
5340 $questionsHavingResultRecord
5343 return $questionsMissingResultRecordt;
5349 $ilDB = $DIC[
'ilDB'];
5353 FROM tst_test_result 5354 WHERE active_fi = %s 5355 AND question_fi = %s 5359 $row =
$ilDB->fetchAssoc(
$ilDB->queryF(
$query, array(
'integer',
'integer',
'integer'), array($activeId, $questionId,
$pass)));
5361 return $row[
'cnt'] > 0;
5370 $valuePairs = array();
5372 foreach ($indexedValues as $value1 => $value2) {
5373 $valuePairs[] = array(
'value1' => $value1,
'value2' => $value2);
5385 $indexedValues = array();
5387 foreach ($valuePairs as $valuePair) {
5388 $indexedValues[ $valuePair[
'value1'] ] = $valuePair[
'value2'];
5391 return $indexedValues;
5413 $ilDB = $DIC[
'ilDB'];
5416 "UPDATE qpl_questions SET tstamp = %s WHERE question_id = %s",
5417 array(
'integer',
'integer'),
5418 array(time(), $this->
getId())
5439 if ($this->testQuestionConfigInstance === null) {
5456 include_once(
'Modules/TestQuestionPool/classes/class.ilTestQuestionConfig.php');
static _getUserIdFromActiveId($active_id)
isInUse($question_id="")
Checks whether the question is in use or not.
static isObligationPossible($questionId)
returns boolean wether it is possible to set this question type as obligatory or not considering the ...
static isCoreQuestionType($questionType)
static resetOriginalId($questionId)
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
deletePageOfQuestion($question_id)
Deletes the page object of a question with a given ID.
afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
getId()
Gets the id of the assQuestion object.
static _getManualScoringTypes()
Retrieve the manual scoring settings as type strings.
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms public
saveToDb($original_id="")
Saves the question to the database.
static getListByQuestionId($questionId)
instantiates a question hint list for the passed question id
static _getWorkingTimeOfParticipantForPass($active_id, $pass)
Returns the complete working time in seconds for a test participant.
static isFileAvailable($file)
$export_image_path
(Web) Path to images
Test Question configuration.
static _getQuestionText($a_q_id)
Returns question text.
getFlashPathWeb()
Returns the web image path for web accessable flash applications of a question.
static _instanciateQuestion($question_id)
Creates an instance of a question with a given question id.
static getAllowedImageMaterialFileExtensions()
static _getOriginalId($question_id)
Returns the original id of a question.
static getPluginObject(string $a_ctype, string $a_cname, string $a_slot_id, string $a_pname)
formatSAQuestion($a_q)
Format self assessment question.
setSuggestedSolution($solution_id="", $subquestion_index=0, $is_import=false)
Sets a suggested solution for the question.
fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
Receives parameters from a QTI parser and creates a valid ILIAS question object.
static getObjectClassNameByQuestionType($questionType)
Taxonomy node <-> item assignment.
migrateContentForLearningModule(ilAssSelfAssessmentMigrator $migrator)
static _includeClass($question_type, $gui=0)
Include the php class file for a given question type.
static _updateTestResultCache($active_id, ilAssQuestionProcessLocker $processLocker=null)
Move this to a proper place.
static getQuestionTypeFromDb($question_id)
get question type for question id
static _isWriteable($object_id, $user_id)
Returns true, if the question pool is writeable by a given user.
forceExistingIntermediateSolution($activeId, $passIndex, $considerDummyRecordCreation)
_getTotalAnswers($a_q_id)
get number of answers for question id (static) note: do not use $this inside this method ...
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
static sumTimesInISO8601FormatH_i_s_Extended($time1, $time2)
static _getParticipantData($active_id)
Retrieves a participant name from active id.
_questionExistsInPool($question_id)
Returns true if the question already exists in the database and is assigned to a question pool...
copySuggestedSolutionFiles($source_questionpool_id, $source_question_id)
static getNumExistingSolutionRecords($activeId, $pass, $questionId)
returns the number of existing solution records for the given test active / pass and given question i...
duplicateIntermediateSolutionAuthorized($activeId, $passIndex)
buildHashedImageFilename($plain_image_filename, $unique=false)
getSuggestedSolutionPath()
Returns the path for a suggested solution.
getTitleFilenameCompliant()
returns the object title prepared to be used as a filename
static _getQuestionType($question_id)
Returns the question type of a question with a given id.
static _getSolutionMaxPass($question_id, $active_id)
Returns the maximum pass a users question solution.
static getUsageOfObject($a_obj_id, $a_include_titles=false)
Get usage of object.
static lookupResultRecordExist($activeId, $questionId, $pass)
getQuestionType()
Returns the question type of the question.
static includeCoreClass($questionType, $withGuiClass)
syncSkillAssignments($srcParentId, $srcQuestionId, $trgParentId, $trgQuestionId)
static _getTotalRightAnswers($a_q_id)
get number of answers for question id (static) note: do not use $this inside this method ...
getPoints()
Returns the maximum available points for the question.
static originalQuestionExists($questionId)
static _isUsedInRandomTest($question_id="")
Checks whether the question is used in a random test or not.
copyPageOfQuestion($a_q_id)
questionTitleExists($questionpool_id, $title)
Returns TRUE if the question title exists in the database.
toXML($a_include_header=true, $a_include_binary=true, $a_shuffle=false, $test_output=false, $force_image_references=false)
Returns a QTI xml representation of the question.
const ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT
constant for additional content editing mode "pageobject"
buildTestPresentationConfig()
build basic test question configuration instance
static getQuestionsMissingResultRecord($activeId, $pass, $questionIds)
__set($key, $value)
Object setter.
__get($value)
Object getter.
Abstract basic class which is to be extended by the concrete assessment question type classes...
static _needsManualScoring($question_id)
& _getSuggestedSolution($question_id, $subquestion_index=0)
Returns a suggested solution for a given subquestion index.
setDefaultNrOfTries($a_defaultnroftries)
Set Default Nr of Tries.
addQTIMaterial(&$a_xml_writer, $a_material, $close_material_tag=true, $add_mobs=true)
Creates a QTI material tag from a plain text or xhtml text.
static prepareTextareaOutput($txt_output, $prepare_for_latex_output=false, $omitNl2BrWhenTextArea=false)
Prepares a string for a text area output where latex code may be in it If the text is HTML-free...
static _getIdForImportId($a_import_id)
get current object id for import id (static)
createPageObject()
create page object of question
intermediateSolutionExists($active_id, $pass)
adjustReachedPointsByScoringOptions($points, $active_id, $pass=null)
Adjust the given reached points by checks for all special scoring options in the test container...
ensureNonNegativePoints($points)
deleteAnswers($question_id)
Deletes datasets from answers tables.
deleteDummySolutionRecord($activeId, $passIndex)
calculateResultsFromSolution($active_id, $pass=null, $obligationsEnabled=false)
Calculates the question results from a previously saved question solution.
static & _instanciateQuestionGUI($question_id)
Creates an instance of a question gui with a given question id.
static _areAnswered($a_user_id, $a_question_ids)
Checks if an array of question ids is answered by an user or not.
getSuggestedSolutionTitle($subquestion_index=0)
Returns the title of a suggested solution at a given subquestion_index.
$additinalContentEditingMode
getSolutionValues($active_id, $pass=null, $authorized=true)
Loads solutions of a given user from the database an returns it.
getQuestionChangeListeners()
setId($id=-1)
Sets the id of the assQuestion object.
copyXHTMLMediaObjectsOfQuestion($a_q_id)
static _getQuestionTypeName($type_tag)
Return the translation for a given question type tag.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
duplicateSkillAssignments($srcParentId, $srcQuestionId, $trgParentId, $trgQuestionId)
static isForcePassResultUpdateEnabled()
static _getSuggestedSolutionCount($question_id)
Returns the number of suggested solutions associated with a question.
getUserSolutionPreferingIntermediate($active_id, $pass=null)
getImagePathWeb()
Returns the web image path for web accessable images of a question.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
removeResultRecord($activeId, $pass)
createRandomSolution($test_id, $user_id)
createNewQuestion($a_create_page=true)
Creates a new question without an owner when a new question is created This assures that an ID is giv...
static includePluginClass($questionType, $withGuiClass)
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second. ...
migrateToLmContent($content)
lmMigrateQuestionTypeSpecificContent(ilAssSelfAssessmentMigrator $migrator)
static _lookupTitle($a_id)
lookup object title
static _getIdForImportId($a_type, $a_target)
Get current id for an import id.
syncSuggestedSolutionFiles($original_id)
Syncs the files of a suggested solution if the question is synced.
syncXHTMLMediaObjectsOfQuestion()
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assQuestion constructor
beforeSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
getAdditionalContentEditingMode()
getter for additional content editing mode for this question
getJavaPath()
Returns the image path for web accessable images of a question.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
deleteAdditionalTableData($question_id)
Deletes datasets from the additional question table in the database.
getParticipantsSolution()
isAnswered($active_id, $pass=null)
returns boolean wether the question is answered during test pass or not
setEstimatedWorkingTimeFromDurationString($durationString)
Sets the estimated working time of a question from a given datetime string.
getSelfAssessmentEditingMode()
Get Self-Assessment Editing Mode.
isAddableAnswerOptionValue($qIndex, $answerOptionValue)
setNrOfTries($a_nr_of_tries)
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
static lookupParentObjId($questionId)
ilDBInterface $ilDB
isHTML($a_text)
Checks if a given string contains HTML or not.
static _getObjectIDFromActiveID($active_id)
Returns the ILIAS test object id for a given active id.
loadFromDb($question_id)
Loads the question from the database.
persistPreviewState(ilAssQuestionPreviewSession $previewSession)
persists the preview state for current user and question
authorizedSolutionExists($active_id, $pass)
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
setShuffle($shuffle=true)
Sets the shuffle flag.
static _replaceMediaObjectImageSrc($a_text, $a_direction=0, $nic=IL_INST_ID)
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
getObjId()
Get the object id of the container object.
getValidAdditionalContentEditingModes()
getter for valid additional content editing modes
static _getMaximumPoints($question_id)
Returns the maximum points, a learner can reach answering the question.
getShuffle()
Gets the shuffle flag.
$arrData
Associative array to store properties.
static _getAllReferences($a_id)
get all reference ids of object
isValidAdditionalContentEditingMode($additionalContentEditingMode)
returns the fact wether the passed additional content mode is valid or not
& getInstances()
Gets all instances of the question.
fetchIndexedValuesFromValuePairs(array $valuePairs)
setParticipantsSolution($participantSolution)
setProcessLocker($processLocker)
static _getInternalLinkHref($target="")
isPreviewSolutionCorrect(ilAssQuestionPreviewSession $previewSession)
static _getQuestionInfo($question_id)
Returns question information from the database.
static convertISO8601FormatH_i_s_ExtendedToSeconds($time)
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
static isQuestionObligatory($question_id)
checks wether the question with given id is marked as obligatory or not
static deleteHintsByQuestionIds($questionIds)
Deletes all question hints relating to questions included in given question ids.
getSuggestedSolution($subquestion_index=0)
Returns a suggested solution for a given subquestion index.
authorizedOrIntermediateSolutionExists($active_id, $pass)
removeSolutionRecordById($solutionId)
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
duplicateQuestionHints($originalQuestionId, $duplicateQuestionId)
addAnswerOptionValue($qIndex, $answerOptionValue, $points)
static _getLogLanguage()
retrieve the log language for assessment logging
persistWorkingState($active_id, $pass=null, $obligationsEnabled=false, $authorized=true)
persists the working state for current testactive and testpass
supportsJavascriptOutput()
Returns true if the question type supports JavaScript output.
getJavaPathWeb()
Returns the web image path for web accessable java applets of a question.
getFlashPath()
Returns the image path for web accessable flash files of a question.
static isAllowedImageMimeType($mimeType)
getTestId()
Gets the test id of the assQuestion object.
setAuthor($author="")
Sets the authors name of the assQuestion object.
setObligationsToBeConsidered($obligationsToBeConsidered)
catch(Exception $e) $message
Assessment hint page object.
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
getAuthor()
Gets the authors name of the assQuestion object.
getTotalAnswers()
get total number of answers
getQuestionTypeID()
Returns the question type of the question.
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question.
static _updateQuestionCount($object_id)
Updates the number of available questions for a question pool in the database.
foreach($_POST as $key=> $value) $res
static _getQuestionCountAndPointsForPassOfParticipant($active_id, $pass)
areObligationsToBeConsidered()
static setForcePassResultUpdateEnabled($forcePassResultsUpdateEnabled)
updateCurrentSolutionsAuthorization($activeId, $pass, $authorized, $keepTime=false)
static _isWorkedThrough($active_id, $question_id, $pass=null)
Returns true if the question was worked through in the given pass Worked through means that the user ...
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
static _addLog($user_id, $object_id, $logtext, $question_id="", $original_id="", $test_only=false, $test_ref_id=null)
Add an assessment log entry.
log($active_id, $langVar)
static _getScoreCutting($active_id)
Determines if the score of a question should be cut at 0 points or the score of the whole test...
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static _getResultPass($active_id)
Retrieves the pass number that should be counted for a given user.
static explodeKeyValues($keyValues)
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
static _lookupObjId($a_id)
setOutputType($outputType=OUTPUT_HTML)
Sets the output type.
isComplete()
Returns true, if a question is complete for use.
static _getCountSystem($active_id)
Gets the count system for the calculation of points.
static setResultGateway($resultGateway)
static implodeKeyValues($keyValues)
static $forcePassResultsUpdateEnabled
getQuestion()
Gets the question string of the question object.
getComment()
Gets the comment string of the assQuestion object.
static lookupOriginalParentObjId($originalQuestionId)
returns the parent object id for given original question id (should be a qpl id, but theoretically it...
redirection script todo: (a better solution should control the processing via a xml file) ...
getHtmlUserSolutionPurifier()
static createDirectory($a_dir, $a_mod=0755)
create directory
static saveOriginalId($questionId, $originalId)
$nr_of_tries
Number of tries.
static _lookupAuthor($obj_id)
Gets the authors name of the ilObjTest object.
getSuggestedSolutionPathWeb()
Returns the web path for a suggested solution.
static _updateObjectiveResult($a_user_id, $a_active_id, $a_question_id)
static signFile($path_to_file)
moveUploadedMediaFile($file, $name)
Move an uploaded media file to an public accessible temp dir to present it.
getDefaultNrOfTries()
Get Default Nr of Tries.
isClone($question_id="")
Checks whether the question is a clone of another question or not.
updateCurrentSolution($solutionId, $value1, $value2, $authorized=true)
static removeTrailingPathSeparators($path)
cleanupMediaObjectUsage()
synchronises appearances of media objects in the question with media object usage table ...
deleteSuggestedSolutions()
Deletes all suggestes solutions in the database.
setPreventRteUsage($a_val)
Set prevent rte usage.
fixSvgToPng($imageFilenameContainingString)
static _instantiateQuestion($question_id)
isDummySolutionRecord($solutionRecord)
setExternalId($external_id)
fetchValuePairsFromIndexedValues(array $indexedValues)
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
static duplicateListForQuestion($originalQuestionId, $duplicateQuestionId)
duplicates a hint list from given original question id to given duplicate question id and returns an ...
isAdditionalContentEditingModePageObject()
isser for additional "pageobject" content editing mode
getTestOutputSolutions($activeId, $pass)
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
static $allowedCharsetsByMimeType
const ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT
constant for additional content editing mode "default"
static _questionExistsInTest($question_id, $test_id)
setPoints($a_points)
Sets the maximum available points for the question.
saveQuestionDataToDb($original_id="")
_resolveIntLinks($question_id)
static _getSuggestedSolutionOutput($question_id)
Returns the output of the suggested solution.
const KEY_VALUES_IMPLOSION_SEPARATOR
onDuplicate($originalParentId, $originalQuestionId, $duplicateParentId, $duplicateQuestionId)
Will be called when a question is duplicated (inside a question pool or for insertion in a test) ...
_questionExists($question_id)
Returns true if the question already exists in the database.
static _getInstanceByType($a_type)
Factory method for creating purifier instances.
static $imageSourceFixReplaceMap
getOwner()
Gets the creator/owner ID of the assQuestion object.
static isAllowedImageFileExtension($mimeType, $fileExtension)
lmMigrateQuestionTypeGenericContent(ilAssSelfAssessmentMigrator $migrator)
lookupCurrentTestPass($active_id, $pass)
resetUsersAnswer($activeId, $pass)
getEstimatedWorkingTime()
Gets the estimated working time of a question.
setQuestion($question="")
Sets the question string of the question object.
removeCurrentSolution($active_id, $pass, $authorized=true)
setTestId($id=-1)
Sets the test id of the assQuestion object.
ensureCurrentTestPass($active_id, $pass)
prepareTextareaOutput($txt_output, $prepare_for_latex_output=false, $omitNl2BrWhenTextArea=false)
Prepares a string for a text area output in tests.
deleteSolutionRecordByValues($activeId, $passIndex, $authorized, $matchValues)
$testQuestionConfigInstance
getTestPresentationConfig()
Get the test question configuration (initialised once)
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
Creates an Excel worksheet for the detailed cumulated results of this question.
buildImagePath($questionId, $parentObjectId)
getRequestStatisticData()
removeExistingSolutions($activeId, $pass)
setOriginalId($original_id)
static getResultGateway()
setLastChange($lastChange)
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass...
getAnswerTableName()
Returns the name of the answer table in the database.
static _deleteAllLinksOfSource($a_source_type, $a_source_id, $a_lang="-")
Delete all links of a given source.
static buildExamId($active_id, $pass, $test_obj_id=null)
removeIntermediateSolution($active_id, $pass)
getReachedPoints($active_id, $pass=null)
Returns the points, a learner has reached answering the question This is the fast way to get the poin...
$selfassessmenteditingmode
static getGuiClassNameByQuestionType($questionType)
getTitle()
Gets the title string of the assQuestion object.
static _cleanupMediaObjectUsage($a_text, $a_usage_type, $a_usage_id)
Synchronises appearances of media objects in $a_text with media object usage table.
static setTokenMaxLifetimeInSeconds($token_max_lifetime_in_seconds)
getAdjustedReachedPoints($active_id, $pass=null, $authorizedSolution=true)
returns the reached points ...
deleteTaxonomyAssignments()
addQuestionChangeListener(ilQuestionChangeListener $listener)
static isHTML($a_text)
Checks if a given string contains HTML or not.
static fetchMimeTypeIdentifier($contentTypeString)
if(empty($password)) $table
$obligationsToBeConsidered
static _getReachedPoints($active_id, $question_id, $pass=null)
Returns the points, a learner has reached answering the question.
pcArrayShuffle($array)
Shuffles the values of a given array.
duplicateSuggestedSolutionFiles($parent_id, $question_id)
Duplicates the files of a suggested solution if the question is duplicated.
static _saveLink( $a_source_type, $a_source_id, $a_target_type, $a_target_id, $a_target_inst=0, $a_source_lang="-")
save internal link information
getOutputType()
Gets the output type.
onCopy($sourceParentId, $sourceQuestionId, $targetParentId, $targetQuestionId)
Will be called when a question is copied (into another question pool)
getSuggestedSolutions()
Return the suggested solutions.
getHtmlQuestionContentPurifier()
static $allowedImageMaterialFileExtensionsByMimeType
_resolveInternalLink($internal_link)
setTitle($title="")
Sets the title string of the assQuestion object.
fixUnavailableSkinImageSources($html)
setObjId($obj_id=0)
Set the object id of the container object.
getActiveUserData($active_id)
Returns the user id and the test id for a given active id.
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
setExportImagePath($a_path)
setComment($comment="")
Sets the comment string of the assQuestion object.
setShuffler(ilArrayElementShuffler $shuffler)
static $allowedFileExtensionsByMimeType
static getFeedbackClassNameByQuestionType($questionType)
static _getQuestionTitle($question_id)
Returns the question title of a question with a given id.
static getKeyValuesImplosionSeparator()
static _setReachedPoints($active_id, $question_id, $points, $maxpoints, $pass, $manualscoring, $obligationsEnabled)
Sets the points, a learner has reached answering the question Additionally objective results are upda...
static _getTitle($a_q_id)
Returns the title of a question.
static instantiateQuestionGUI($a_question_id)
Creates an instance of a question gui with a given question id.
keyInArray($searchkey, $array)
returns TRUE if the key occurs in an array
$GLOBALS['JPEG_Segment_Names']
Global Variable: XMP_tag_captions.
removeAllExistingSolutions()
QTIMaterialToString($a_material)
Reads an QTI material tag an creates a text string.
getSuggestedSolutionOutput()
getSelfAssessmentFormatter()
isNonEmptyItemListPostSubmission($postSubmissionFieldname)
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
setSelfAssessmentEditingMode($a_selfassessmenteditingmode)
Set Self-Assessment Editing Mode.
static missingResultRecordExists($activeId, $pass, $questionIds)
getSolutionRecordById($solutionId)
getPreventRteUsage()
Get prevent rte usage.
static _isWriteable($question_id, $user_id)
Returns true if the question is writeable by a certain user.
static getAllowedFileExtensionsForMimeType($mimeType)